Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::shared_ptr and initializer lists

Tags:

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. 
like image 583
dpj Avatar asked Aug 05 '12 23:08

dpj


People also ask

What is STD initializer list?

An object of type std::initializer_list<T> is a lightweight proxy object that provides access to an array of objects of type const T .

What are initializer lists in C++?

The initializer list is used to directly initialize data members of a class. An initializer list starts after the constructor name and its parameters.

Are initializer lists more efficient?

So yes, initialisation lists are, magic compilers aside, more efficient, and also, IMHO, easier to read. the compiler could only "elide" the default construction through the "as-if" rule, so it needs to be able to figure out there is no difference.

Does initializer list run before constructor?

As already answered, initialization lists get completely executed before entering the constructor block. So it is completely safe to use (initialized) members in the constructor body.


1 Answers

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.

like image 83
Howard Hinnant Avatar answered Sep 28 '22 03:09

Howard Hinnant