如何使用 std::optional<T>::emplace 的第二个重载
Posted
技术标签:
【中文标题】如何使用 std::optional<T>::emplace 的第二个重载【英文标题】:How to use second overload of 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 normalA1, 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(A1, 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
重载的示例。
【问题讨论】:
可能使emplace(1,2,3, allocator);
为optional<vector<int>>
工作。即使没有分配器参数,也需要重载。
【参考方案1】:
但不应该首先 emplace 重载 T& emplace( Args&&... args );够了吗?
这不是因为 braced-init-list,即 1, 2, 3
没有类型。因为它没有类型,所以编译器无法推断Args
应该是什么。我们需要有一个显式采用std::initializer_list
的重载,这样我们就可以避免编译器无法推断出 braced-init-list 应该被视为什么。
【讨论】:
以上是关于如何使用 std::optional<T>::emplace 的第二个重载的主要内容,如果未能解决你的问题,请参考以下文章
通过引用传递 std::optional<T> 是不是实际上保存复制?
如何在 if 语句中最好地测试和解包 std::optional
带有 std::any 和 std::optional 的 any_cast
如何优雅处理多参数返回/无参数返回——std::optional