Reputation: 14632
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]'
tuple<int, int> t2={1, 2};
^
Upvotes: 31
Views: 9317
Reputation: 218840
In addition to Praetorian's correct answer (which I've upvoted), I wanted to add a little more information...
Post-C++14, the standard has been changed to allow:
tuple<int, int> t2={1, 2};
to compile and have the expected semantics. The proposal that does this is N4387. This will also allow constructs such as:
tuple<int, int>
foo()
{
return {1, 2};
}
It only allows it if all T
in the tuple
are implicitly contructible from all arguments.
As a non-conforming extension, libc++ already implements this behavior.
Upvotes: 31
Reputation: 109159
The tuple
constructor you're trying to call is explicit
, so copy-list-initialization will fail. The corresponding pair
constructor is not explicit
.
Change your code to
tuple<int, int> t2{1, 2};
and it'll compile.
Upvotes: 27