Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::initializer_list with Multiple Types

I'm having trouble with std::initializer_list. I reduced it down to a simple example:

#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;
}

When compiled using g++ test_initializer.cpp -std=c++0x, it compiles and runs well. However, if line 11 is changed to Test({1,2.0});, one gets:

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&&’

I suspect this happens because the compiler can't figure out what type to make the initializer list. Is there a way to fix the example so that it works with different types (and still uses initializer lists)?

like image 445
imallett Avatar asked Jan 13 '14 22:01

imallett


1 Answers

An std::initializer_list takes only one type. If you need different types, you can use variadic templates:

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

/* ... */

int main()
{
    Test(1, 2.0);
}
like image 152
David G Avatar answered Nov 16 '22 03:11

David G