Date: Fri, 15 Nov 2019 20:58:47 +0100
Hi,
Consider
std::vector<std::unique_ptr<Widget>> v = {
std::make_unique<Widget>(1),
std::make_unique<Widget>(2),
}; // ERROR: call to deleted copy ctor requested
which doesn't work because unique_ptr isn't copyable.
This is unfortunate, because the following works as expected:
std::unique_ptr<Widget> v[] = {
std::make_unique<Widget>(1),
std::make_unique<Widget>(2),
}; // OK
We're therefore back in a situation where std::vector cannot be
initialized like a C array, something we wanted to fix with
initializer_list.
The design paper for initializer_list, wg21.link/N2215 has an example,
in the Q&A section, describing a scenario where modification of an
initializer_list's elements might backfire:
int f() {
Odd_vector<int> = {1, 2, 3};
return v[0];
};
f();
f();
f();
If Odd_vector's ctor changed the first element in the initializer_list,
then subsequent calls to f() would produce different values.
However, the final wording, wg21.link/N2675, binds the lifetime of the
implicit array to the lifetime of the initializer_object:
> The lifetime of the array is the same as that of the initializer_list
> object.
By this token, the array needs to be re-created for each invocation of
f() (though there's an escape hatch by which compilers are allowed to
store the array in read-only memory, too).
I presume the paper has been written pre-move-semantics.
Have there been attempts since to reconcile move semantics and
initializer_list? Pointers welcome.
Thanks,
Marc
Consider
std::vector<std::unique_ptr<Widget>> v = {
std::make_unique<Widget>(1),
std::make_unique<Widget>(2),
}; // ERROR: call to deleted copy ctor requested
which doesn't work because unique_ptr isn't copyable.
This is unfortunate, because the following works as expected:
std::unique_ptr<Widget> v[] = {
std::make_unique<Widget>(1),
std::make_unique<Widget>(2),
}; // OK
We're therefore back in a situation where std::vector cannot be
initialized like a C array, something we wanted to fix with
initializer_list.
The design paper for initializer_list, wg21.link/N2215 has an example,
in the Q&A section, describing a scenario where modification of an
initializer_list's elements might backfire:
int f() {
Odd_vector<int> = {1, 2, 3};
return v[0];
};
f();
f();
f();
If Odd_vector's ctor changed the first element in the initializer_list,
then subsequent calls to f() would produce different values.
However, the final wording, wg21.link/N2675, binds the lifetime of the
implicit array to the lifetime of the initializer_object:
> The lifetime of the array is the same as that of the initializer_list
> object.
By this token, the array needs to be re-created for each invocation of
f() (though there's an escape hatch by which compilers are allowed to
store the array in read-only memory, too).
I presume the paper has been written pre-move-semantics.
Have there been attempts since to reconcile move semantics and
initializer_list? Pointers welcome.
Thanks,
Marc
Received on 2019-11-15 14:01:09