私は次のコードを持っています:
struct Foo {
int var1;
int var2;
friend std::ostream& operator<<(std::ostream& os, const Foo& s){
return os << "[Foo] " << s.var1 << "," << s.var2 ;
}
};
int main() {
Foo foo;
foo.var1 = 1;
foo.var2 = 2;
std::list<Foo> list;
list.push_back(foo);
Foo &foo2 = list.front();
foo2.var2 = 5;
std::cout << "foo (" << &foo << "): " << foo << std::endl;
std::cout << "foo2 (foo from list) (" << &list.front() << "): " << foo2 << std::endl;
}
との両方foo
でfoo2
同じオブジェクトを参照したい。私が割り当てるときそう5
にfoo2.var2
、私が変更したいと思うfoo.var2
だけでなく。しかし、次の出力でわかるように、これは発生していません。
foo (0x7fffffffe140): [Foo] 1,2
foo2 (foo from list) (0x61ac30): [Foo] 1,5
それを行う正しい方法は何でしょうか?
を使用push_back
して要素をリストにpush_back
挿入すると、リストに挿入されるコピーが作成されます。解決策はstd::reference_wrapper
、リストの基になるタイプとして代わりにを使用することです。
std::list<std::reference_wrapper<Foo>> lst;
そしてそれを次のように押し込みます
lst.push_back(foo);
これは、それがどのように機能するかを示す非常に簡単な例です。
#include <functional>
#include <iostream>
#include <list>
int main()
{
int i = 42;
std::list<std::reference_wrapper<int>> lst;
lst.push_back(i); // we add a "reference" into the list
lst.front().get() = 10; // we update the list
std::cout << i; // the initial i was modified!
}
のreference_wrapper
ように参照のリストを単純に作成することはできないため、が必要ですstd::list<Foo&>
。または、ポインタを使用することもできますが、reference_wrapper
アプローチはより透過的です。
上記の簡単な例でstd::reference_wrapper::get()
は、基になる参照を取得するためにを使用する必要があることに注意してください。これreference_wrapper
は、が代入演算子の左側にあり、int
[を介して暗黙的に変換されないためstd::reference_wrapper::operator T&
です。
以下は、reference_wrapper
sを使用するように変更された完全に機能するコードです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加