将花括号初始化程序完美转发到构造函数?

Perfect forwarding of a braced initializer to a constructor?

有类似的问题,不过none好像是这样的

我有一个包装器 class 用来容纳 S。在最简单的形式中,我们有

// A simple class with a two-argument constructor:
struct S {
    int x[2];
    S(int x, int y) : x{x, y} {}
};

struct WrappedSSimple {
    S s;
    template <typename... Args>
    WrappedSSimple(Args&&... args) : s(std::forward<Args>(args)...) {}
};

当我调用 WrappedSSimple({1,2}) 时似乎有效。但是,我想让 c'tor 私有并具有静态工厂功能。失败了:

struct WrappedS {
    S s;
    template <typename... Args>
    static WrappedS make(Args&&... args) { return WrappedS(std::forward<Args>(args)...); }
private:
    template <typename... Args>
    WrappedS(Args&&... args) : s(std::forward<Args>(args)...) {}
};

<source>:28:14: error: no matching function for call to 'make'
    auto w = WrappedS::make({1,2}); // This is not.
             ^~~~~~~~~~~~~~
<source>:19:21: note: candidate template ignored: substitution failure: deduced incomplete pack <(no value)> for template parameter 'Args'
    static WrappedS make(Args&&... args) { return WrappedS(std::forward<Args>(args)...); }
                    ^

https://godbolt.org/z/rsWK94Thq

有没有办法通过staticmake函数完美转发大括号?

在您的第一个示例中,WrappedSSimple({1,2}) 正在调用 WrappedSSimple 的 move-constructor,并使用通过 user-defined 构造函数构建的临时变量作为参数。

如果构造函数是私有的,则无法使用工厂复制此行为,因为需要访问构造函数的临时对象始终是在调用者的上下文中创建的。

你也不能一般地转发非类型化的大括号。如果您可以将大括号的每个元素的类型限制为相同,那么您可以做的最好的事情是使用 std::initializer_list 或对数组的引用作为 make 的参数。