26

std :: shared_ptrコンストラクターが期待どおりに動作していません:

#include <iostream>
#include <vector>

void func(std::vector<std::string> strings)
{
    for (auto const& string : strings)
    {
        std::cout << string << '\n';
    }
}

struct Func
{
    Func(std::vector<std::string> strings)
    {
        for (auto& string : strings)
        {
            std::cout << string << '\n';
        }
    }
};

int main(int argc, const char * argv[])
{

    func({"foo", "bar", "baz"});
    Func({"foo", "bar", "baz"});
    //auto ptr = std::make_shared<Func>({"foo", "bar", "baz"}); // won't compile.
    //auto ptr = std::make_shared<Func>{"foo", "bar", "baz"}; // nor this.
    return 0;
}

私は何か間違ったことをしていますか、それともコンパイラですか?コンパイラは次のとおりです。

$ clang ++ --version Apple clangバージョン4.0(tags / Apple / clang-421.0.57)(LLVM 3.1svnに基づく)

編集:make_sharedの代わりにshared_ptr。

エラーは次のとおりです。

make -k 
clang++ -std=c++11 -stdlib=libc++    main.cc   -o main
main.cc:28:18: error: no matching function for call to 'make_shared'
      auto ptr = std::make_shared<Func>({"foo", "bar", "baz"});
                 ^~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/c++/v1/memory:4621:1: note: candidate function not viable:
     requires 0 arguments, but 1 was provided
make_shared(_Args&& ...__args)
^
1 error generated.
4

3 に答える 3

34

これを試して:

auto ptr = std::make_shared<Func>(std::initializer_list<std::string>{"foo", "bar", "baz"});

Clangはのタイプを推測することをいとわない{"foo", "bar", "baz"}。現在、それが言語の動作方法であるかどうか、またはコンパイラのバグを調べているかどうかはわかりません。

于 2012-08-06T00:00:25.057 に答える
5

のコンストラクターは、動的に割り当てられたリソース(または少なくとも削除者が解放できるもの)を指すと想定される、shared_ptr<T>型のポインターを引数として取ります。T*一方、make_shared構築は自動的に行われ、コンストラクター引数を直接取得します。

だからあなたはこれを言う:

std::shared_ptr<Foo> p(new Foo('a', true, Blue));

または、はるかに優れた効率的な方法:

auto p = std::make_shared<Foo>('a', true, Blue);

後者の形式は、割り当てと構築を処理し、その過程でより効率的な実装を作成します。

もちろん言うこともできますがmake_shared<Foo>(Foo('a', true, Blue))、それは不要なコピー(省略される可能性があります)を作成するだけであり、さらに重要なことに、不要な冗長性を作成します。[編集]ベクターを初期化するには、これが最良の方法かもしれません。

auto p = std::make_shared<Func>(std::vector<std::string>({"a", "b", "c"}));

ただし、重要な点は、make_shared 動的割り当てを実行するのに対し、shared-ptrコンストラクターは実行せ、代わりに所有権を取得することです。

于 2012-08-05T23:33:18.390 に答える
3

make_sharedこれらの引数から構築され、が指す新しいオブジェクトを作成する場合は、を使用する必要がありますshared_ptrshared_ptr<T>はへのポインタのようなものです。これは、ではなく、へのポインタTを使用して作成する必要があります。TT

編集:初期化リストが含まれている場合、完全な転送は実際にはまったく完全ではありません(これは最悪です)。コンパイラのバグではありません。タイプの右辺値をFunc手動で作成する必要があります。

于 2012-08-05T23:29:35.950 に答える