The following code compiles with clang (libc++) and fails with gcc (libstdc++). Why does gcc (libstdc++) complains about an initializer list? I thought the return argument was using uniform initialization syntax.
std::tuple<double,double> dummy() {
return {2.0, 3.0};
}
int main() {
std::tuple<double,double> a = dummy();
return 0;
}
Error: line 22: converting to ‘std::tuple’ from initializer \
list would use explicit constructor ‘constexpr std::tuple<_T1, _T2>::tuple(_U1&\
&, _U2&&) [with _U1 = double; _U2 = double; = void; _T\
1 = double; _T2 = double]’
Note: GCC (libstdc++) (and clang (libc++)) accept
std::tuple<double,double> dummy {1.0, 2.0};
Isn’t it the same case?
Update: this is a libc++ extension, see http://llvm.org/bugs/show_bug.cgi?id=15299 and also answer by Howard Hinnant below.
Unlike for
pair<>, implicit construction of atuple<>is not possible unfortunately. You have to usemake_tuple():std::tuplehas a variadic constructor, but it is marked asexplicit. Thus, it cannot be used in this situation, where a temporary must be implicitly constructible. Per Paragraph 20.4.2 of the C++11 Standard:For the same reason it is illegal to use copy-initialization syntax for initializing tuples:
Or to construct a tuple implicitly when passing it as an argument to a function:
Accordingly, if you construct your
std::tupleexplicitly when returning it indummy(), no compilation error will occur: