std::shared_ptr and initializer lists

dpj picture dpj · Aug 6, 2012 · Viewed 18.5k times · Source

The std::shared_ptr constructor isn't behaving as I expected:

#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;
}

Am I doing something wrong or is the compiler? The compiler is:

$ clang++ --version Apple clang version 4.0 (tags/Apple/clang-421.0.57) (based on LLVM 3.1svn)

edit: shared_ptr instead of make_shared.

Here's the error:

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.

Answer

Howard Hinnant picture Howard Hinnant · Aug 6, 2012

Try this:

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

Clang is not willing to deduce the type of {"foo", "bar", "baz"}. I'm currently not sure whether that is the way the language is supposed to work, or if we're looking at a compiler bug.