如何使用 std::optional<T>::emplace 的第二个重载

Pta*_*666 3 c++ stdoptional

std::optional::emplace 文档中有一个接受的重载std::initializer_list

template< class U, class... Args >
T& emplace( std::initializer_list<U> ilist, Args&&... args );
Run Code Online (Sandbox Code Playgroud)

前提是

std::is_constructible<T, std::initializer_list&, Args&&...>::value 为真

我认为它可能用于放置 POD 类型,但显然这不是它的工作方式(在其他 SO 主题中解释说emplace函数使用()语法而不是{}):

struct A
{
    int x;
    int y;
    int z;
};
int main()
{
    A normalA{1, 2, 3};  // this is OK
    std::cout << std::is_constructible<A, std::initializer_list<int>&, int, int, int>::value << std::endl;  // false
    std::cout << std::is_constructible<A, std::initializer_list<int>&>::value << std::endl;  // false
    std::optional<A> optA;
    // optA.emplace({1, 2, 3});  // this is NOK
    optA.emplace(A{1, 2, 3});  // I can walk it around with copy-ctor
}

Run Code Online (Sandbox Code Playgroud)

我可以编写接受的构造函数initializer_list

struct B
{
    B(std::initializer_list<int> l) {/* some impl here */}
    int x;
    int y;
    int z;
};
Run Code Online (Sandbox Code Playgroud)

然后emplace像这样调用:

    std::optional<B> optB;
    optB.emplace({1, 2, 3});
Run Code Online (Sandbox Code Playgroud)

但不应该首先emplace过载T& emplace( Args&&... args );就足够了吗?我认为它可能对数组类型有用,但std::optional<int[]> xxx;无论如何都不能编译。

您能否提供一些std::optional::emplace使用第二个重载的示例。

Nat*_*ica 6

但不应该首先放置重载 T& emplace( Args&&... args ); 够了吗?

这不是因为支撑初始化列表,即{1, 2, 3}没有类型。因为它没有类型,所以编译器无法推断出Args应该是什么。我们需要有一个显式采用 a 的重载,std::initializer_list以便我们可以避免编译器无法推断出花括号初始化列表应该被视为什么。