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.
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 .
The initializer list is used to directly initialize data members of a class. An initializer list starts after the constructor name and its parameters.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With