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

标签 c++ stdoptional

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

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

std::is_constructible<T, std::initializer_list&, Args&&...>::value is true


我认为它可能用于放置 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& emplace( Args&&... args );够了吗?
我认为它可能对数组类型有用,但是 std::optional<int[]> xxx;无论如何都不能编译。
您能否提供一些示例,其中第二个 std::optional::emplace使用了过载。

最佳答案

but shouldn't first emplace overload T& emplace( Args&&... args ); be enough for that?


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

关于c++ - 如何使用 std::optional<T>::emplace 的第二个重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67906729/

相关文章:

c++ - 为什么我的 WM_UNICHAR 处理程序从未被调用?

c++ - 在 CPP 中为变量动态分配数据类型

c++ - std::optional::value_or() - 惰性参数评估

c++ - 如何最好地测试和解包std::if语句中的可选

c++ - nullptr、{} 和 nullopt 之间的区别

c++ - QT 不清楚的移位运算符行为

c++ - 在C++中的本地范围内使用Lambda

c++ - 抽象类,继承和虚拟析构函数

c++ - 为什么 std::optional operator* 没有 has_value() 的 Debug模式断言?

C++17:使用 std::optional 评估枚举是否包含值