std:: список инициализаторов с несколькими типами
У меня возникли проблемы с 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 ответов:
An
std::initializer_listпринимает только один тип. Если вам нужны разные типы, вы можете использовать вариадические шаблоны:template<typename... Args> Test(Args&&... args); /* ... */ int main() { Test(1, 2.0); }
Пусть 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; }
Comments