In the std::optional::emplace
docs there is an overload that accepts std::initializer_list
:
template< class U, class... Args >
T& emplace( std::initializer_list<U> ilist, Args&&... args );
provided that
std::is_constructible<T, std::initializer_list&, Args&&...>::value is true
I thought that it might be used to emplace POD types, but apparently this is not how it works (in other SO topics it was explained that emplace
functions are using ()
syntax instead of {}
):
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
}
I can write the constructor accepting initializer_list
:
struct B
{
B(std::initializer_list<int> l) {/* some impl here */}
int x;
int y;
int z;
};
and then call emplace
like this:
std::optional<B> optB;
optB.emplace({1, 2, 3});
but shouldn't first emplace
overload T& emplace( Args&&... args );
be enough for that?
I thought that it might be useful for the array types, but std::optional<int[]> xxx;
does not compile anyway.
Can you please provide some example where second std::optional::emplace
overload is used.
emplace({1,2,3}, allocator);
work foroptional<vector<int>>
. Even without the allocator argument the overload is required. – Freya