The answer Andy Prowl gives is correct. I wanted to comment on the libc++ implementation, and the comment format does not allow me enough room or formatting choices.
Daniel Krügler and I had a conversation about a year ago on this subject, and he convinced me that this issue was worthy putting an extension into libc++ to get field experience with. And so far the feedback has been positive. However I want to make clear: This is not as simple as removing explicit
from the ctor explicit constexpr tuple(UTypes&&...)
.
Daniel's plan is to give tuple
a constructor that perfectly respects each element's implicit/explicit construction. And if every element will construct implicitly from every argument in the initializer list, then the tuple construction is implicit, else it will be explicit.
For example:
Given:
#include <tuple>
struct A
{
};
struct B
{
B() = default;
B(A);
};
struct C
{
C() = default;
explicit C(A);
};
Then:
std::tuple<>
test0()
{
return {}; // ok
}
Nothing much to say about that one. But also this is ok:
std::tuple<B>
test1B()
{
return {A()}; // ok B(A) implicit
}
because the conversion from A
to B
is implicit. However the following is a compile time error:
std::tuple<C>
test1C()
{
return {A()}; // error, C(A) is explicit
}
because the conversion from A
to C
is explicit. This logic continues for multi-element tuples. For an implicit conversion to happen, every element must have an implicit conversion from the argument list:
std::tuple<A, B>
test2B()
{
return {A(), A()}; // ok each element has implicit ctor
}
std::tuple<A, C>
test2C()
{
return {A(), A()}; // error, C(A) is explicit
}
I should emphasize: This is a libc++ extension at this time.
Update
chico made a good suggestion that I update this answer:
Since this answer was given, Daniel Krügler wrote a paper and presented it to the C++ committee in Bristol this past April. Although the paper was well received, it was reviewed too late in the week to vote it into the current working draft.
Update
Daniel's proposal is now part of the current working draft. The libc++ implementation is now set to become standard in this regard for the next C++ standard (C++17 we hope).