Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template parameter deduction for constructors from initializer list

At the Kona meeting, template parameter deduction for constructors (P0091R0) has been approved. It simplifies some variable definitions:

std::pair   p  {1,2};     // o.k., constructor pair<int,int>(1,2)
std::vector v1 (10, 0);   // o.k., 10 zeroes, constructor vector<int>(size_t n, T initvalue)
std::vector v2 {10, 0};   // o.k., 2 values: 10, 0, apparently initializer list?
std::vector v3 = {10, 0}; // o.k., same as v2?

However, the following lines do not compile in gcc 7 HEAD 201611 version (live example):

std::vector v4 = {3};     // error: no matching function for call to 'std::vector(int)'
std::vector v5 {1, 2, 3}; // error: 'int' is not a class
std::set    s  {1, 2, 3}; // error: no matching function for call to 'std::set(int,int,int)'

Are these just "a bridge too far", since they involve initializer lists? Are they covered by template type parameter deduction? Will they be allowed, when compilers conform to C++1z?

like image 857
René Richter Avatar asked May 25 '26 18:05

René Richter


2 Answers

You need an extra pair of curly braces to make your code work correctly:

std::vector v4 = {{1, 5}}; 
std::vector v5 {{1, 2, 3}};  
std::set    s  {{1, 2, 3}};
like image 120
Vittorio Romeo Avatar answered May 30 '26 12:05

Vittorio Romeo


Because you want to call the foo::foo(const initializer_list &) constructor, you need to tell the compiler that there's exactly one argument, so you need an extra pair of parentheses or braces:

std::vector v5 ({1, 2, 3});
std::set    s  ({1, 2, 3});
               ^         ^

In this way, the compiler knows that you're calling a function with only one argument as const initializer_list &, instead of a function with three ints.

like image 32
iBug Avatar answered May 30 '26 11:05

iBug



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!