std::shared_ptr and initializer lists

前端 未结 3 678
广开言路
广开言路 2020-12-09 16:37

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

#include 
#include 

void func(std::vector st         


        
相关标签:
3条回答
  • 2020-12-09 17:06

    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.

    0 讨论(0)
  • 2020-12-09 17:12

    You need to use make_shared if you want to create a new object, constructed from those arguments, pointed to by a shared_ptr. shared_ptr<T> is like a pointer to T- it needs to be constructed with a pointer to T, not a T.

    Edit: Perfect forwarding is in fact not at all perfect when initializer lists are involved (which is the suck). It's not a bug in the compiler. You will have to create an rvalue of type Func manually.

    0 讨论(0)
  • 2020-12-09 17:15

    The constructor of shared_ptr<T> takes a pointer of type T* as its argument, assumed to point to a dynamically allocated resource (or at least something that can be freed by the deleter). On the other hand, make_shared does the construction for you and takes the constructor arguments directly.

    So either you say this:

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

    Or, much better and more efficiently:

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

    The latter form takes care of the allocation and construction for you, and in the process creates a more efficient implementation.

    You could of course also say make_shared<Foo>(Foo('a', true, Blue)), but that would just create an unnecessary copy (which may be elided), and more importantly it creates needless redundancy. [Edit] For initializing your vector, this may be the best method:

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

    The important point is, though, that make_shared performs the dynamic allocation for you, while the shared-ptr constructor does not, and instead takes ownership.

    0 讨论(0)
提交回复
热议问题