Andy Prowl の答えは正しいです。libc++ の実装についてコメントしたかったのですが、コメント形式では十分なスペースや形式の選択肢がありません。
Daniel Krügler と私は約 1 年前にこの件について話し合い、この問題は libc++ に拡張機能を追加して現場での経験を積む価値があると確信させてくれました。そしてこれまでのところ、フィードバックは肯定的です。ただし、明確にしたいのですが、これはexplicitctor から削除するほど簡単ではありませんexplicit constexpr tuple(UTypes&&...)。
ダニエルの計画は、tuple各要素の暗黙的/明示的な構築を完全に尊重するコンストラクターを提供することです。また、すべての要素が初期化子リストのすべての引数から暗黙的に構築される場合、タプルの構築は暗黙的であり、それ以外の場合は明示的になります。
例えば:
与えられた:
#include <tuple>
struct A
{
};
struct B
{
B() = default;
B(A);
};
struct C
{
C() = default;
explicit C(A);
};
それで:
std::tuple<>
test0()
{
return {}; // ok
}
それについては何も言うことはありません。しかし、これも問題ありません:
std::tuple<B>
test1B()
{
return {A()}; // ok B(A) implicit
}
からAへの変換Bは暗黙的であるためです。ただし、次はコンパイル時エラーです。
std::tuple<C>
test1C()
{
return {A()}; // error, C(A) is explicit
}
からAへの変換Cは明示的であるためです。このロジックは、複数要素のタプルにも適用されます。暗黙的な変換を行うには、すべての要素に引数リストからの暗黙的な変換が必要です。
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
}
強調しておきますが、これは現時点では libc++ の拡張機能です。
アップデート
チコは、この回答を更新することを提案しました。
この回答が与えられたので、Daniel Krügler は論文を書き、この 4 月にブリストルの C++ 委員会に提出しました。この論文は好評でしたが、現在の作業草案に投票するには週の後半にレビューされました。
アップデート
Daniel の提案は現在、現在の作業草案の一部です。libc++ の実装は、この点で次の C++ 標準 (C++17 を希望) の標準になるように設定されています。