更新 2:このバグは、r191150 の Clang で修正されました。GCC は適切なエラー メッセージを表示してコードを拒否します。
更新:バグ レポートを送信しました。次のコードは、clang++ 3.4 (トランク 191037) を搭載した私のマシンでのコードです。
#include <iostream>
#include <memory>
int main()
{
std::unique_ptr<int> u_ptr(new int(42));
std::cout << " u_ptr.get() = " << u_ptr.get() << std::endl;
std::cout << "*u_ptr = " << *u_ptr << std::endl;
auto s_ptr = std::make_shared<int>(std::move(u_ptr));
std::cout << "After move" << std::endl;
std::cout << " u_ptr.get() = " << u_ptr.get() << std::endl;
std::cout << "*u_ptr = " << *u_ptr << std::endl;
std::cout << " s_ptr.get() = " << s_ptr.get() << std::endl;
std::cout << "*s_ptr = " << *s_ptr << std::endl;
}
これを印刷します:
u_ptr.get() = 0x16fa010
*u_ptr = 42
After move
u_ptr.get() = 0x16fa010
*u_ptr = 42
s_ptr.get() = 0x16fa048
*s_ptr = 1
ご覧のとおり、unique_ptr
は移動されていません。標準では、移動後に null になることが保証されています。はshared_ptr
間違った値を指しています。
奇妙なことに、警告なしでコンパイルされ、valgrind は問題、リーク、ヒープの破損を報告しません。変。
の代わりにa への右辺値参照を取る ctor を使用s_ptr
して作成すると、適切な動作が示されます。shared_ptr
unique_ptr
make_shared
#include <iostream>
#include <memory>
int main()
{
std::unique_ptr<int> u_ptr(new int(42));
std::cout << " u_ptr.get() = " << u_ptr.get() << std::endl;
std::cout << "*u_ptr = " << *u_ptr << std::endl;
std::shared_ptr<int> s_ptr{std::move(u_ptr)};
std::cout << "After move" << std::endl;
std::cout << " u_ptr.get() = " << u_ptr.get() << std::endl;
//std::cout << "*u_ptr = " << *u_ptr << std::endl; // <-- would give a segfault
std::cout << " s_ptr.get() = " << s_ptr.get() << std::endl;
std::cout << "*s_ptr = " << *s_ptr << std::endl;
}
それは印刷します:
u_ptr.get() = 0x5a06040
*u_ptr = 42
After move
u_ptr.get() = 0
s_ptr.get() = 0x5a06040
*s_ptr = 42
ご覧のとおりu_ptr
、標準で必要な移動後は null でありs_ptr
、正しい値を指しています。これは正しい動作です。
(元の答え。)
Simple が指摘しているように、「Foo に std::unique_ptr を取るコンストラクターがない限り、コンパイルしないでください。」
少し拡張すると、make_shared
引数が T のコンストラクターに転送されます。unique_ptr<T>&&
T がコンパイル エラーであることを受け入れることができる ctor を持っていない場合。
ただし、このコードを修正して必要なものを取得するのは簡単です (オンライン デモ)。
#include <memory>
using namespace std;
class widget { };
int main() {
unique_ptr<widget> uptr{new widget};
shared_ptr<widget> sptr(std::move(uptr));
}
ポイントはmake_shared
、この状況で使用するのは間違っているということです。shared_ptr
には、 を受け入れるctor があります。の ctor で (13) をunique_ptr<Y,Deleter>&&
参照してください。shared_ptr