如何使用 std::optional<T>::emplace 的第二个重载
How to use second overload of std::optional<T>::emplace
在 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?
不是因为 braced-init-list,即 {1, 2, 3}
没有类型。因为它没有类型,所以编译器无法推断出 Args
应该是什么。我们需要有一个显式接受 std::initializer_list
的重载,这样我们就可以避免编译器无法推断出 braced-init-list 应该被视为什么。
在 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?
不是因为 braced-init-list,即 {1, 2, 3}
没有类型。因为它没有类型,所以编译器无法推断出 Args
应该是什么。我们需要有一个显式接受 std::initializer_list
的重载,这样我们就可以避免编译器无法推断出 braced-init-list 应该被视为什么。