具有多种类型的std :: initializer_list

时间:2014-01-13 22:24:59

标签: c++11 initializer-list variadic-functions

我在使用std :: initializer_list时遇到了麻烦。我把它简化为一个简单的例子:

#include <initializer_list>
#include <cstdio>


class Test {
    public:
        template <typename type> Test(const std::initializer_list<type>& args) {}
};

int main(int argc, char* argv[]) {
    Test({1,2});

    getchar();
    return 0;
}

使用g++ test_initializer.cpp -std=c++0x编译时,它编译并运行良好。但是,如果第11行更改为Test({1,2.0});,则会获得:

ian@<host>:~/Desktop$ g++ test_initializer.cpp -std=c++0x
test_initializer.cpp: In function ‘int main(int, char**)’:
test_initializer.cpp:11:14: error: no matching function for call to ‘Test::Test(<brace-enclosed initializer list>)’
test_initializer.cpp:11:14: note: candidates are:
test_initializer.cpp:7:28: note: template<class type> Test::Test(const std::initializer_list<_Tp>&)
test_initializer.cpp:5:7: note: constexpr Test::Test(const Test&)
test_initializer.cpp:5:7: note:   no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘const Test&’
test_initializer.cpp:5:7: note: constexpr Test::Test(Test&&)
test_initializer.cpp:5:7: note:   no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘Test&&’

我怀疑发生这种情况是因为编译器无法弄清楚要创建初始化列表的类型。有没有办法修复示例,以便它可以使用不同的类型(并仍然使用初始化列表)?

2 个答案:

答案 0 :(得分:6)

std::initializer_list只接受一种类型。如果您需要不同的类型,可以使用可变参数模板:

template<typename... Args>
Test(Args&&... args);

/* ... */

int main()
{
    Test(1, 2.0);
}

答案 1 :(得分:-4)

让initializer_list保存最随意的指针void *,并从那里执行自己的转换。这是一个例子。

#include <initializer_list>
#include <iostream>

using std::initializer_list;
using std::cout;
using std::endl;

class Person {
    private:
        string _name;
        int _age;
    public:
        Person(initializer_list<void*> init_list) {
            auto it = init_list.begin();
            _name = *((string*)(*it));
            it++;
            _age = *((int*)(*it));
        }
        void print() {
            cout << "name: " << _name << ". age: " << _age << endl;
        }
};

int main(void) {
    string name{"Vanderbutenburg};
    int age{23};
    Person p{&name,&age};
    p.print(); // "name: Vanderbutenburg. age: 23"

    return 0;
}