【问题标题】:How to use second overload of std::optional<T>::emplace如何使用 std::optional<T>::emplace 的第二个重载
【发布时间】:2021-08-26 14:38:46
【问题描述】:

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

template< class U, class... Args >
T& emplace( std::initializer_list<U> ilist, Args&&... args );

前提是

std::is_constructible::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
}

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

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

然后像这样调用emplace

    std::optional<B> optB;
    optB.emplace({1, 2, 3});

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

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

【问题讨论】:

  • 可能使emplace({1,2,3}, allocator);optional&lt;vector&lt;int&gt;&gt; 工作。即使没有分配器参数,也需要重载。

标签: c++ stdoptional


【解决方案1】:

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

这不是因为 braced-init-list,即 {1, 2, 3} 没有类型。因为它没有类型,所以编译器无法推断Args 应该是什么。我们需要有一个显式采用std::initializer_list 的重载,这样我们就可以避免编译器无法推断出 braced-init-list 应该被视为什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 2014-06-24
    • 2017-05-14
    • 1970-01-01
    • 2022-06-10
    • 2020-08-15
    • 1970-01-01
    相关资源
    最近更新 更多