このコードサンプルでは、S
に渡される一時的な文字列の有効期間に関するルールは何ですか?標準によれば集計参照メンバーと一時的な生涯
struct S
{
// [1] S(const std::string& str) : str_{str} {}
// [2] S(S&& other) : str_{std::move(other).str} {}
const std::string& str_;
};
S a{"foo"}; // direct-initialization
auto b = S{"bar"}; // copy-initialization with rvalue
std::string foobar{"foobar"};
auto c = S{foobar}; // copy-initialization with lvalue
const std::string& baz = "baz";
auto d = S{baz}; // copy-initialization with lvalue-ref to temporary
:コンストラクタのCTOR-イニシャライザ(12.6.2)で基準部材への一時的なバウンド(N4296で除去)
N4140 12.2 P5.1
コンストラクターが終了するまで続きます。
N4296 12.6.2 P8
MEM-初期における基準部材に結合された一時的発現は悪い形成されています。
したがって、[1]
のようなユーザー定義のコンストラクタを持つことは、われわれが望むものではありません。それは最新のC++ 14で不正な形になっていることさえありますか?gccもclangも警告していません。
直接集計の初期化で変更されますか?私はそのように見える、一時的な生涯が延長されます。
コピーの初期化に関して、Default move constructor and reference membersは暗黙的に[2]
が生成されると述べています。移動が省略される可能性があることを考慮して、暗黙的に生成された移動コンストラクターにも同じ規則が適用されますか?
a, b, c, d
には有効な参照がありますか?
集約初期化の一時ファイルの存続期間の延長から例外がありません。したがって、一時ファイルの存続期間が延長されます。これにより、「直接初期化」の場合に作成された一時的なものの適切な有効期間が保証されます。 – dyp
「その動きは逃げられるかもしれない」ということは何を意味しますか?参照バインディングは省略できません。 'str_'は' other.str'に直接バインドされます。 ( 'std :: move'は効果がありません) –
@ M.Mほとんどのコンパイラは、移動コンストラクタを使用するのではなく直接初期化を実行します。はい。 'std :: move(other).str'は参照のために' other.str'と同じであり、ここでは何の効果もありません – 3XX0