具体的には、ダイレクトリスト初期化(cppreference.com(3))です。std :: make_shared/std :: make_uniqueがリストの初期化を使用しない理由はありますか?
両方std::make_shared
と均一初期機能はC++ 11に導入されました。したがって、ヒープ上にオブジェクトを割り当てる際に集約初期化を使用することができます。new Foo{1, "2", 3.0f}
。これは、集約、ポッドなどのコンストラクタを持たないオブジェクトを直接初期化するのに最適です。
カジュアル構造体を関数内に効率的に宣言するなどの実際のシナリオは、ラムダは、私の経験では、非常に一般的になった:
void foo()
{
struct LambdaArgs
{
std::string arg1;
std::string arg2;
std::string arg3;
};
auto args = std::make_shared<LambdaArgs>(LambdaArgs{"1", "2", "3"});
auto lambda = [args] {
/// ...
};
/// Use lambda
/// ...
}
ここauto args = std::make_shared<LambdaArgs>("1", "2", "3");
はいいことwhouldが、std::make_shared
は通常として実装されているので、仕事に行くされていません。
template<typename T, typename... Args>
std::shared_ptr<T> make_shared(Args && ...args)
{
return std::shared_ptr<T>(new T(std::forward<Args>(args)...));
}
だから我々はauto args = std::make_shared<LambdaArgs>(LambdaArgs{"1", "2", "3"});
と付き合っている。
std::make_shared
で解決されるはずの問題は、コンストラクタのないオブジェクトに対しても引き続き発生します。また、この回避策は、美的ではないだけでなく効率も悪くなります。
これは別の見落としであるか、この選択肢を守る理由がいくつかあります。具体的には、どのような落とし穴は、リストの初期化ソリューションにすることができますか? std::make_unique
は、C++ 14に後で導入されました。なぜ同じパターンに従っていますか?
あなたの質問に答えることはできませんが、回避策:カジュアルな構造体の代わりにタプルを使用する場合は、適切なコンストラクタが提供され、さらに軽い: 'LambdaArgs = std :: tuple '; –
Frank
'std :: make_shared'が解決している問題は、オブジェクトが作成された後でshared_ptrが所有権を取得する前に例外がスローされた場合、すべてが正しくクリーンアップされていることを確認することです。それは軽微な見落としのように見えます。 – Kevin
これは興味深いかもしれません:http://stackoverflow.com/questions/24234480/stdmake-shared-with-stdinitializer-list – marcinj