[解決済み】auto&&は何を教えてくれるの?
質問
のようなコードを読むと
auto&& var = foo();
ここで
foo
の型の値で返す任意の関数です。
T
. そして
var
への参照であるrvalue型のlvalueです。
T
. しかし、これが意味するのは
var
? の資源を盗んでいいということでしょうか?
var
? を使うべき合理的な場面はありますか?
auto&&
を返すときのように、コードの読者に何かを伝えることができます。
unique_ptr<>
を使えば、排他的所有権を持っていることがわかるのでは?また、例えば次のような場合はどうでしょう。
T&&
とすると
T
はクラス型ですか?
の他の使用例があるかどうか、理解したいだけです。
auto&&
この記事の例で説明されているような、テンプレート・プログラミングにおけるものとは異なります。
ユニバーサルリファレンス
Scott Meyersによるものです。
解決するには?
を使用することで
auto&& var = <initializer>
と言っているようなものです。
lvalue式かrvalue式かに関係なく、どんなイニシャライザーでも受け入れ、その定数性を保持します。
. これは通常
転送
(通常
T&&
). これがうまくいくのは、"universal reference"があるからです。
auto&&
または
T&&
にバインドされます。
何でも
.
と言うかもしれません。
const auto&
なぜなら
また
何にでもバインドするのか?を使うことの問題点は
const
の参照は、それが
const
! のマークがついていないメンバ関数を呼び出したり、const でない参照にバインドすることはできません。
const
.
例として、あなたが
std::vector
で、その最初の要素にイテレータを取り、そのイテレータが指す値を何らかの方法で変更します。
auto&& vec = some_expression_that_may_be_rvalue_or_lvalue;
auto i = std::begin(vec);
(*i)++;
このコードは、イニシャライザーの表現に関係なく、問題なくコンパイルできます。の代替となるのは
auto&&
は以下のように失敗します。
auto => will copy the vector, but we wanted a reference
auto& => will only bind to modifiable lvalues
const auto& => will bind to anything but make it const, giving us const_iterator
const auto&& => will bind only to rvalues
だから、これには
auto&&
は完璧に機能します! の使用例です。
auto&&
このように、範囲指定された
for
のループになります。参照
その他の質問
をご覧ください。
もし、あなたが
std::forward
の上で
auto&&
を参照し、それが元々 lvalue か rvalue のどちらかであったという事実を保持するように、あなたのコードに書かれています。
lvalueまたはrvalue式からオブジェクトを取得したので、最も効率的に使用できるように、元々持っていた値を保持したいのです - これは無効になるかもしれません。
というように。
auto&& var = some_expression_that_may_be_rvalue_or_lvalue;
// var was initialized with either an lvalue or rvalue, but var itself
// is an lvalue because named rvalues are lvalues
use_it_elsewhere(std::forward<decltype(var)>(var));
これにより
use_it_elsewhere
は、元のイニシャライザーが変更可能なrvalueであった場合、パフォーマンスのため(コピーを避けるため)に、その内臓を引き裂くことができます。
からリソースを盗めるかどうか、いつ盗めるかについて、これは何を意味するのでしょうか。
var
? さて
auto&&
は何にでもバインドされるから、それを取り除くことはできない。
var
の中身は、lvalue や const でさえあるかもしれません。しかし、私たちは
std::forward
を他の関数に渡すと、その内部を完全に破壊してしまうかもしれません。これを実行したら、すぐに
var
は無効な状態である。
では、これを応用して
auto&& var = foo();
質問で示されたように、foo は
T
を値で指定します。この場合、私たちは確実に
var
と推論されます。
T&&
. rvalueであることは確実なので、このような場合は
std::forward
の許可を得て、そのリソースを盗むことができます。この具体的な事例では
を知っていること
foo
は値で返す
と読者は読めばいいのです。
から返された一時的なものへのrvalueの参照を取っている。
foo
だから、そこから楽しく移動することができるんだ。
補足として、以下のような表現がある場合、言及する価値があると思います。
some_expression_that_may_be_rvalue_or_lvalue
が出てくるかもしれません。それは、quot;well your code might change"という状況とは別のものです。ここでは、その例を挙げてみましょう。
std::vector<int> global_vec{1, 2, 3, 4};
template <typename T>
T get_vector()
{
return global_vec;
}
template <typename T>
void foo()
{
auto&& vec = get_vector<T>();
auto i = std::begin(vec);
(*i)++;
std::cout << vec[0] << std::endl;
}
ここです。
get_vector<T>()
は、ジェネリックタイプによってL値にもR値にもなりうる素敵な式です。
T
. の戻り値の型を変更するのです。
get_vector
のテンプレートパラメータを通して
foo
.
を呼び出すと
foo<std::vector<int>>
,
get_vector
を返します。
global_vec
を値で指定すると、rvalue 式が得られる。あるいは
foo<std::vector<int>&>
,
get_vector
を返します。
global_vec
を参照し、lvalue 式を生成します。
そうすると
foo<std::vector<int>>();
std::cout << global_vec[0] << std::endl;
foo<std::vector<int>&>();
std::cout << global_vec[0] << std::endl;
予想通り、次のような出力が得られました。
2
1
2
2
を変更するとしたら
auto&&
のいずれかに変更します。
auto
,
auto&
,
const auto&
または
const auto&&
となると、望むような結果は得られない。
の有無によってプログラムロジックを変更する方法もあります。
auto&&
参照がlvalueまたはrvalue式で初期化されている場合、型特性を使用することができます。
if (std::is_lvalue_reference<decltype(var)>::value) {
// var was initialised with an lvalue expression
} else if (std::is_rvalue_reference<decltype(var)>::value) {
// var was initialised with an rvalue expression
}
関連
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] ルール・オブ・スリーとは?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] ムーブセマンティクスとは何ですか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
-
[解決済み】C++11のラムダ式って何?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】coutはstdのメンバではない
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】致命的なエラー LNK1169: ゲームプログラミングで1つ以上の多重定義されたシンボルが発見された
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] 警告:暗黙の定数変換でのオーバーフロー
-
[解決済み] std::forwardはどのように機能するのですか?重複] [重複
-
[解決済み] const参照クラスのメンバはテンポラリーを長持ちさせるか?