[解決済み] C++ std::ref(T)とT&の違い?
質問
このプログラムについて、いくつか質問があります。
#include <iostream>
#include <type_traits>
#include <functional>
using namespace std;
template <typename T> void foo ( T x )
{
auto r=ref(x);
cout<<boolalpha;
cout<<is_same<T&,decltype(r)>::value;
}
int main()
{
int x=5;
foo (x);
return 0;
}
と出力されます。
false
知りたいのは、もし
std::ref
がオブジェクトの参照を返さないのなら、それは何をするのでしょうか?基本的に、何が違うのでしょうか。
T x;
auto r = ref(x);
と
T x;
T &y = x;
また、「なぜこのような違いがあるのか?なぜ
std::ref
または
std::reference_wrapper
を参照する場合(つまり
T&
)?
どのように解決するのですか?
さて
ref
は、適切な
reference_wrapper
型のオブジェクトを構築し、オブジェクトへの参照を保持します。つまり、適用すると
auto r = ref(x);
これは
reference_wrapper
への直接の参照ではなく
x
(つまり
T&
). これは
reference_wrapper
(すなわち
r
を保持する代わりに
T&
.
A
reference_wrapper
をエミュレートしたい場合に非常に便利です。
reference
をエミュレートしたい場合に非常に便利です。
コピーコンストラクタブル
と
コピーアサイン可能
).
C++では、一度参照を作成すると(例えば
y
という) オブジェクトへの参照 (例えば
x
) に変換すると
y
となり
x
は同じ
ベースアドレス
. さらに
y
は他のオブジェクトを参照することはできません。また
参照の配列
このようなコードはエラーになります。
#include <iostream>
using namespace std;
int main()
{
int x=5, y=7, z=8;
int& arr[] {x,y,z}; // error: declaration of 'arr' as array of references
return 0;
}
しかしこれは合法です。
#include <iostream>
#include <functional> // for reference_wrapper
using namespace std;
int main()
{
int x=5, y=7, z=8;
reference_wrapper<int> arr[] {x,y,z};
for (auto a: arr)
cout << a << " ";
return 0;
}
/* OUTPUT:
5 7 8
*/
で悩みを相談する
cout << is_same<T&,decltype(r)>::value;
を使えば、解決します。
cout << is_same<T&,decltype(r.get())>::value; // will yield true
プログラムをお見せします。
#include <iostream>
#include <type_traits>
#include <functional>
using namespace std;
int main()
{
cout << boolalpha;
int x=5, y=7;
reference_wrapper<int> r=x; // or auto r = ref(x);
cout << is_same<int&, decltype(r.get())>::value << "\n";
cout << (&x==&r.get()) << "\n";
r=y;
cout << (&y==&r.get()) << "\n";
r.get()=70;
cout << y;
return 0;
}
/* Ouput:
true
true
true
70
*/
ここで、3つのことを知ることができます。
-
A
reference_wrapper
オブジェクト(ここではr
) を使用することで 参照の配列 では不可能だったT&
. -
r
は、実際には本当の参照のように振る舞います。r.get()=70
の値を変更したy
). -
r
とは異なります。T&
とは異なりますがr.get()
は これはつまりr
が持つT&
は、その名前が示すように を包むラッパーです。T&
.
この回答が、あなたの疑問を説明するのに十分すぎるほどであることを願っています。
関連
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された
-
[解決済み】c++で.txtファイルから2次元の配列に読み込む
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 割り当て後にリストが予期せず変更されました。その理由と防止策を教えてください。
-
[解決済み] const int*、const int * const、int const *の違いは何ですか?
-
[解決済み] 私的相続、公的相続、保護相続の違いについて
-
[解決済み] g++とgccの違いは何ですか?
-
[解決済み] キーワード「ref」と「out」の違いは何ですか?
-
[解決済み] JavaにおけるSoftReferenceとWeakReferenceの違いは何ですか?
最新
-
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-stringを使用すると警告が表示される。"ローカル変数に関連するスタックメモリのアドレスが返される"
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】「Expected '(' for function-style cast or type construction」エラーの意味とは?
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
-
[解決済み] std::reference_wrapperとシンプルポインタの違い?