首页 > 解决方案 > 有没有办法在旧版本的 c++(c++11 之前)中实现初始化列表(种类)?

问题描述

我试图在旧版本的 c++ 中实现(有点:)初始化列表。像下面..

#include <vector>
#include <cstdarg>
#include <iostream>

using namespace std;

template <class T>
vector <T> VEC_VA(size_t argCount,T arg1, ... )
{
    va_list arguments;
    vector <T> sList;

    va_start ( arguments, argCount);
    for ( int x = 0; x < (int)argCount; x++ )
        sList.push_back(va_arg ( arguments, T));
    va_end ( arguments );

    return sList;
}

struct Test
{
    Test(int _x,std::string _s):x(_x),s(_s){}
    int x;
    std::string s;
};

void methodWithArgs(vector<Test> testObjs)
{
    cout<<"Size:"<<testObjs.size()<<endl;
    for (std::vector<Test>::const_iterator it = testObjs.begin();it != testObjs.end();++it)
        std::cout << it->x <<":"<< it->s.c_str()<< std::endl;
}

int main()
{
    methodWithArgs(VEC_VA(2,Test(1,"one"),Test(2,"two")));
    return 0;
}

但这种实现适用于 Visual Studio 2012 (v11.0)。但不是在 Linux g++ 编译器中。并以错误结束:“无法通过'...'传递非平凡可复制类型'struct Test'的对象”

那么有没有更好的主意呢?

标签: c++initializer-list

解决方案


如果您愿意接受稍微不同的语法,那么您所需要的只是vector::push_back()返回对向量的引用的版本。像这样的东西:

#include <vector>
#include <iostream>

template<typename T>
class VEC_VA_HELP {
   std::vector<T> vector;
public:
   VEC_VA_HELP(T arg1) : vector() { vector.push_back(arg1); }
   VEC_VA_HELP &operator()(T arg) { vector.push_back(arg); return *this; }
   operator std::vector<T> &() { return vector; }
};
template<typename T>
VEC_VA_HELP<T> VEC_VA(T arg1) { return VEC_VA_HELP<T>(arg1); }

struct Test {
   Test(int _x) : x(_x) {}
   int x;
};

void methodWithArgs(std::vector<Test> const &testObjs) {
   std::cout << testObjs.size() << std::endl;
   for (std::vector<Test>::const_iterator it = testObjs.begin();
        it != testObjs.end();
        ++it)
      std::cout << it->x << std::endl;
}

int
main(void)
{
   methodWithArgs(VEC_VA(Test(1))(Test(2))(Test(3)));
   return 0;
}

还会想到递归模板,但我不确定它们的语法有多干净。另请参阅有关重载逗号运算符的问题。


推荐阅读