list-initialization

Problem with calling a variadic function template when passing brace initialiser list arguments

天涯浪子 提交于 2019-11-30 11:25:49
Consider this function template: template <class... T> void foo (std::tuple<T, char, double> ... x); This invocation works: using K = std::tuple<int, char, double>; foo ( K{1,'2',3.0}, K{4,'5',6.0}, K{7,'8',9.0} ); This one doesn't: foo ( {1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0} ); (gcc and clang both complain about too many arguments for foo ) Why is the second call a problem? Can I rewrite the declaration of foo so that the second call is also accepted? Thee template parameter T is only used to implement variadicity. The actual type is known and fixed, only the number of arguments varies. In

Are ={} and {}-style initializations the same in C++11?

老子叫甜甜 提交于 2019-11-29 17:38:49
问题 C++11 introduced {}-style initializations. But are these two forms T x {...}; T x = {...}; the same? 回答1: They are not exactly the same. Maybe this can be illustrated by a counter-example: struct Foo { explicit Foo(std::initializer_list<int>) {} }; int main() { Foo f0{1, 2, 3}; // OK Foo f1 = {1, 2, 3}; // ERROR } So, the second variant requires that the type be implicitly constructable from an initialization list, whereas the first version doesn't. Note that the same applies for constructors

Why ={} initialization doesn't work for tuple?

孤街浪徒 提交于 2019-11-28 22:51:22
To me a pair is just special case of a tuple , but following surprises me: pair<int, int> p1(1, 2); // ok tuple<int, int> t1(1, 2); // ok pair<int, int> p2={1, 2}; // ok tuple<int, int> t2={1, 2}; // compile error Why there is difference when we use {} to initialize tuple ? I tried even g++ -std=c++1y but still has error: a.cc: In function 'int main()': a.cc:9:29: error: converting to 'std::tuple<int, int>' from initializer list would use explicit constructor 'constexpr std::tuple<_T1, _T2>::tuple(_U1&&, _U2&&) [with _U1 = int; _U2 = int; <template-parameter-2-3> = void; _T1 = int; _T2 = int]'

List-initialization priority from object of same type

我怕爱的太早我们不能终老 提交于 2019-11-28 10:59:31
问题 #include <iostream> #include <initializer_list> using namespace std; struct CL { CL(){} CL (std::initializer_list<CL>){cout<<1;} CL (const CL&){cout<<2;} }; int main() { CL cl1; CL cl2 {cl1}; //prints 21 } Here is CL struct with copy constructor and initializer-list constructor. I think only copy constructor must be called here, because according to C++ 14 Standard, 8.5.4/3 List-initialization of an object or reference of type T is defined as follows: — If T is a class type and the

Does the equal sign make a difference in brace initialization? eg. 'T a = {}' vs 'T a{}'

孤街醉人 提交于 2019-11-28 07:17:09
Here are two ways to initialize a variable in C++11: T a {something}; T a = {something}; I tested these two in all scenarios I could think of and I failed to notice a difference. This answer suggests that there is a subtle difference between the two: For variables I don't pay much attention between the T t = { init }; or T t { init }; styles, I find the difference to be minor and will at worst only result in a helpful compiler message about misusing an explicit constructor. So, is there any difference between the two? The only significant difference I know is in the treatment of explicit

Why ={} initialization doesn't work for tuple?

戏子无情 提交于 2019-11-27 21:36:58
问题 To me a pair is just special case of a tuple , but following surprises me: pair<int, int> p1(1, 2); // ok tuple<int, int> t1(1, 2); // ok pair<int, int> p2={1, 2}; // ok tuple<int, int> t2={1, 2}; // compile error Why there is difference when we use {} to initialize tuple ? I tried even g++ -std=c++1y but still has error: a.cc: In function 'int main()': a.cc:9:29: error: converting to 'std::tuple<int, int>' from initializer list would use explicit constructor 'constexpr std::tuple<_T1, _T2>:

Does copy list initialization invoke copy ctor conceptually?

倾然丶 夕夏残阳落幕 提交于 2019-11-27 18:09:08
问题 Before C++11, we can do copy initialization by writing something like A a = 1; which is more or less equivalent to A a = A(1); . That is, a temporary is first created and then a copy ctor is invoked. Regardless of copy elision, this must be so conceptually and the copy ctor must be accessible. With list initialization in C++11, we can do a copy list initialization by writing A a = {1, 2}; . In my opinion, this should be more or less equivalent to A a = A(1, 2); . However, on GCC and clang, A

Is it possible to invoke a user-defined conversion function via list-initialization?

荒凉一梦 提交于 2019-11-27 15:39:00
Is this program legal? struct X { X(const X &); }; struct Y { operator X() const; }; int main() { X{Y{}}; // ?? error } After n2672 , and as amended by defect 978 , 13.3.3.1 [over.best.ics] has: 4 - However, when considering the argument of a constructor or user-defined conversion function that is a candidate [...] by 13.3.1.7 [...] when the initializer list has exactly one element and a conversion to some class X or reference to (possibly cv-qualified) X is considered for the first parameter of a constructor of X [...], only standard conversion sequences and ellipsis conversion sequences are

C++ Copy constructor gets called instead of initializer_list<>

时光总嘲笑我的痴心妄想 提交于 2019-11-27 14:39:25
Based on this code struct Foo { Foo() { cout << "default ctor" << endl; } Foo(std::initializer_list<Foo> ilist) { cout << "initializer list" << endl; } Foo(const Foo& copy) { cout << "copy ctor" << endl; } }; int main() { Foo a; Foo b(a); // This calls the copy constructor again! //Shouldn't this call the initializer_list constructor? Foo c{b}; _getch(); return 0; } The output is: default ctor copy ctor copy ctor In the third case, I'm putting b into the brace-initialization which should call the initializer_list<> constructor. Instead, the copy constructor takes the lead. Will someone of you

lifetime of a std::initializer_list return value

穿精又带淫゛_ 提交于 2019-11-27 14:18:49
GCC's implementation destroys a std::initializer_list array returned from a function at the end of the return full-expression. Is this correct? Both test cases in this program show the destructors executing before the value can be used: #include <initializer_list> #include <iostream> struct noisydt { ~noisydt() { std::cout << "destroyed\n"; } }; void receive( std::initializer_list< noisydt > il ) { std::cout << "received\n"; } std::initializer_list< noisydt > send() { return { {}, {}, {} }; } int main() { receive( send() ); std::initializer_list< noisydt > && il = send(); receive( il ); } I