関数からいくつかの値を返し、それをタプルにパックしたいと思います。したがって、関数宣言には2つの可能性があります。
std::Tuple<bool, string, int> f()
{
...
return std::make_Tuple(false, "home", 0);
}
そして
std::Tuple<bool, string, int> f()
{
...
return std::forward_as_Tuple(false, "home", 0);
}
これらの関数は同等ですか?これらの機能の間でどちらが好きですか?
std::forward_as_Tuple()
は参照のタプルを作成します。とにかく_Tuple<bool, string, int>
_を返すので、2つは同等になりますこの場合ですが、最初のアプローチの方が明確だと思います-転送しないときにforward_as_Tuple()
を使用します何でも混乱します。
また、コメントでSebastian Redlが述べているように、make_Tuple()
は、コンパイラがコピーの省略を実行できるようにします-C++ 11標準の段落12.8/31に従って、forward_Tuple()
は実行できません(返されるものは、関数の戻り値の型と同じ型ではありません)。
私は好きです、
std::Tuple<bool, std::string, int> f()
{
...
return { false, "home", 0 };
}
上記のコードは、実際にはclang/libc ++トランクの下でコンパイルされています。 @AndyProwlがコメントセクションでコメントしたように、std :: Tupleコンストラクターは明示的であり、初期化リスト構文を介して返されるのはコピー初期化コンテキストであるため、これはすべきではありません。したがって、コピーリスト初期化は、明示的なコンストラクターが一致すると失敗します。
Clang/libc ++が渡される理由はわかりませんが、libc ++のバグだと思います。とにかく、タプルに対してそれができないのは悲しいことです...
一般的に、(私にとっては)それがどれほど悲しいかを実感したと思います。私はその構文に慣れてきましたが、返される型に明示的なコンストラクターが含まれているかどうかを事前に知る必要があります。
これは確かにlibc ++拡張機能です。詳細については、Howard Hinnantの回答をここで確認してください: https://stackoverflow.com/a/14963014 。
現在、libc ++のバグリストでも公開されています: http://llvm.org/bugs/show_bug.cgi?id=15299 。
これは関連する提案です: DanielKrügler、ペアとタプルの改善 。
要するに、これはlibc ++で起こることです:
#include <Tuple>
#include <string>
struct S
{
explicit S(int) {}
};
int main()
{
std::Tuple<int, std::string> t1 = { 1, "hello" }; // ok
std::Tuple<std::string> t2 = "hello"; // ok
std::Tuple<int, S> t3 = { 1, 1 }; // fail: an *element* is to be constructed explicitly
}