在std :: make_shared中使用c ++聚合初始化

tcb*_*tcb 19 c++ c++11

根据我的理解,下面的代码构造一个类型的对象,Foo然后将该对象移动到由分配的内存中std::make_shared

struct Foo
{
    std::string s;
    int i;
    char c;
};

int main(int argc, char* argv[])
{
    auto foo = std::make_shared<Foo>(Foo{"hello", 5, 'c' });
}
Run Code Online (Sandbox Code Playgroud)

是否可以将initialize Foo直接聚合到由std::make_shared?分配的内存中?

mel*_*k47 10

您可以创建一个带有可变参数构造函数模板的适配器来转发参数,例如:

template<class T>
struct aggregate_adapter : public T {
    template<class... Args>
    aggregate_adapter(Args&&... args) : T{ std::forward<Args>(args)... } {}
};
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

auto foo = std::make_shared<aggregate_adapter<Foo>>("hello", 5, 'c');
Run Code Online (Sandbox Code Playgroud)

由于aggregate_adapter<Foo>Foo相关,foo也可以转换std::shared_ptr<Foo>.

注意事项


不幸的是,转发的使用也使得无法在std::make_shared<aggregate_adapter<Foo>>({'h','e','l','l','o'}, 5, 'c');不明确指定类型的情况下对任何成员进行大括号初始化,但同样的限制也适用于make_shared.