Topic: Proposing std::uninitialized_default /


Author: Marc Mutz <marc.mutz@kdab.com>
Date: Tue, 7 Oct 2014 21:14:05 +0200
Raw View
Hi,

I've recently had use of default-constructing a range of T's into
uninitialized memory. When I was filling the range with copies of a T,
std::uninitialized_fill() was a good fit, esp. since it is strongly exception
safe.

But there's no uninitialized_ algorithm for default-constructing a range.

The nearest there is,
   std::uninitialized_fill(first, last, T());
has slightly different semantics, as it invokes the copy contructor instead
(and that one could be deleted).

The same issue plagues the use of raw_memory_iterator.

I ended up writing a loop and a try-catch block :(

So I think there's a place for
  std::uninitialized_default(ForwardIterator first, ForwardIterator last);
(better names welcome).

Since I don't much like the name 'uninitialized_default', I looked for a more
general name / algorithm, and I found "emplace". Emplace without arguments
default-constructs, with one argument or type T, it is a replacement of _fill
(with no intention to deprecate _fill):
   std::uninitialized_emplace(ForwardIterator first, ForwardIterator last,
                   Args&&...args);

Does that make sense?

Thanks,
Marc Mutz

--
Qt Developer Days 2014 - October 6 - 8 at BCC, Berlin

Marc Mutz <marc.mutz@kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Tue, 7 Oct 2014 21:20:46 +0200
Raw View
2014-10-07 21:14 GMT+02:00 Marc Mutz <marc.mutz@kdab.com>:
> Hi,
>
> I've recently had use of default-constructing a range of T's into
> uninitialized memory. When I was filling the range with copies of a T,
> std::uninitialized_fill() was a good fit, esp. since it is strongly exception
> safe.
>
> But there's no uninitialized_ algorithm for default-constructing a range.
>
> The nearest there is,
>    std::uninitialized_fill(first, last, T());
> has slightly different semantics, as it invokes the copy contructor instead
> (and that one could be deleted).
>
> The same issue plagues the use of raw_memory_iterator.
>
> I ended up writing a loop and a try-catch block :(
>
> So I think there's a place for
>   std::uninitialized_default(ForwardIterator first, ForwardIterator last);
> (better names welcome).

No better name suggestion at the very moment at my hand, but the
general idea looks reasonable and safe to me.

> Since I don't much like the name 'uninitialized_default', I looked for a more
> general name / algorithm, and I found "emplace". Emplace without arguments
> default-constructs, with one argument or type T, it is a replacement of _fill
> (with no intention to deprecate _fill):
>    std::uninitialized_emplace(ForwardIterator first, ForwardIterator last,
>                    Args&&...args);
>
> Does that make sense?

I have strong concerns in regard to emplace in that context. Basically
everywhere "emplace" means a potential move of the provided arguments
to construct a single object. This won't work for a potential
multi-construction operation except for special cases (like empty
packs or packs of lvalues to const). People will easily get that
wrong. If you insist on copying the arguments, you could name it
emplace_copy and ensure that the argument pack refers to references to
const.

- Daniel

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: John Bytheway <jbytheway@gmail.com>
Date: Tue, 07 Oct 2014 23:08:17 -0400
Raw View
On 2014-10-07 15:20, Daniel Kr=C3=BCgler wrote:
> 2014-10-07 21:14 GMT+02:00 Marc Mutz <marc.mutz@kdab.com>:
>> Hi,
>>
>> I've recently had use of default-constructing a range of T's into
>> uninitialized memory. When I was filling the range with copies of a T,
>> std::uninitialized_fill() was a good fit, esp. since it is strongly exce=
ption
>> safe.
>>
>> But there's no uninitialized_ algorithm for default-constructing a range=
..
>>
>> The nearest there is,
>>    std::uninitialized_fill(first, last, T());
>> has slightly different semantics, as it invokes the copy contructor inst=
ead
>> (and that one could be deleted).
>>
>> The same issue plagues the use of raw_memory_iterator.
>>
>> I ended up writing a loop and a try-catch block :(
>>
>> So I think there's a place for
>>   std::uninitialized_default(ForwardIterator first, ForwardIterator last=
);
>> (better names welcome).
>=20
> No better name suggestion at the very moment at my hand, but the
> general idea looks reasonable and safe to me.
>=20
>> Since I don't much like the name 'uninitialized_default', I looked for a=
 more
>> general name / algorithm, and I found "emplace". Emplace without argumen=
ts
>> default-constructs, with one argument or type T, it is a replacement of =
_fill
>> (with no intention to deprecate _fill):
>>    std::uninitialized_emplace(ForwardIterator first, ForwardIterator las=
t,
>>                    Args&&...args);
>>
>> Does that make sense?
>=20
> I have strong concerns in regard to emplace in that context. Basically
> everywhere "emplace" means a potential move of the provided arguments
> to construct a single object. This won't work for a potential
> multi-construction operation except for special cases (like empty
> packs or packs of lvalues to const). People will easily get that
> wrong. If you insist on copying the arguments, you could name it
> emplace_copy and ensure that the argument pack refers to references to
> const.

How about

  std::uninitialized_in_place_construct(
    ForwardIterator first, ForwardIterator last, Args const&...args);

Name inspired by
<http://www.boost.org/doc/libs/1_56_0/libs/utility/in_place_factories.html>

Whatever the name, I agree that it shouldn't look like it's using
perfect forwarding, because it can't when more than one element is
constructed.

John Bytheway

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Miro Knejp <miro.knejp@gmail.com>
Date: Wed, 8 Oct 2014 10:25:38 +0200
Raw View
On 08 Oct 2014, at 05:08 , John Bytheway <jbytheway@gmail.com> wrote:

> On 2014-10-07 15:20, Daniel Kr=FCgler wrote:
>> 2014-10-07 21:14 GMT+02:00 Marc Mutz <marc.mutz@kdab.com>:
>>> Hi,
>>>=20
>>> I've recently had use of default-constructing a range of T's into
>>> uninitialized memory. When I was filling the range with copies of a T,
>>> std::uninitialized_fill() was a good fit, esp. since it is strongly exc=
eption
>>> safe.
>>>=20
>>> But there's no uninitialized_ algorithm for default-constructing a rang=
e.
>>>=20
>>> The nearest there is,
>>>   std::uninitialized_fill(first, last, T());
>>> has slightly different semantics, as it invokes the copy contructor ins=
tead
>>> (and that one could be deleted).
>>>=20
>>> The same issue plagues the use of raw_memory_iterator.
>>>=20
>>> I ended up writing a loop and a try-catch block :(
>>>=20
>>> So I think there's a place for
>>>  std::uninitialized_default(ForwardIterator first, ForwardIterator last=
);
>>> (better names welcome).
>>=20
>> No better name suggestion at the very moment at my hand, but the
>> general idea looks reasonable and safe to me.
>>=20
>>> Since I don't much like the name 'uninitialized_default', I looked for =
a more
>>> general name / algorithm, and I found "emplace". Emplace without argume=
nts
>>> default-constructs, with one argument or type T, it is a replacement of=
 _fill
>>> (with no intention to deprecate _fill):
>>>   std::uninitialized_emplace(ForwardIterator first, ForwardIterator las=
t,
>>>                   Args&&...args);
>>>=20
>>> Does that make sense?
>>=20
>> I have strong concerns in regard to emplace in that context. Basically
>> everywhere "emplace" means a potential move of the provided arguments
>> to construct a single object. This won't work for a potential
>> multi-construction operation except for special cases (like empty
>> packs or packs of lvalues to const). People will easily get that
>> wrong. If you insist on copying the arguments, you could name it
>> emplace_copy and ensure that the argument pack refers to references to
>> const.

In the context of the standard library functions labeled "emplace" simply d=
o in-place construction at the destination location. What happens to the ar=
guments is solely the responsibility of the invoked constructor. If you con=
struct multiple objects with the same arguments you better use constructors=
 that behave well in that scenario. But you probably do want to receive arg=
uments as lvalue references in this case just to be safe.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Wed, 8 Oct 2014 11:10:03 +0200
Raw View
2014-10-08 10:25 GMT+02:00 Miro Knejp <miro.knejp@gmail.com>:
> On 08 Oct 2014, at 05:08 , John Bytheway <jbytheway@gmail.com> wrote:
>
>> On 2014-10-07 15:20, Daniel Kr=FCgler wrote:
>>> I have strong concerns in regard to emplace in that context. Basically
>>> everywhere "emplace" means a potential move of the provided arguments
>>> to construct a single object. This won't work for a potential
>>> multi-construction operation except for special cases (like empty
>>> packs or packs of lvalues to const). People will easily get that
>>> wrong. If you insist on copying the arguments, you could name it
>>> emplace_copy and ensure that the argument pack refers to references to
>>> const.
>
> In the context of the standard library functions labeled "emplace" simply=
 do in-place construction at the destination >location.

Yes, I'm aware of that.

>What happens to the arguments is solely the responsibility of the invoked =
constructor.

I'm not denying that, but in the existing contexts of "emplace"
functions the potential harm related to multiple references of the
same arguments to constructed objects does not occur.

> If you construct multiple >objects with the same arguments you better use=
 constructors that behave well in that scenario. But you probably do >want =
to receive arguments as lvalue references in this case just to be safe.

I do not recognize any difference of this response compared to the
arguments that I presented against using the name emplace here. It
would be misleading to use the same name for things that have very
difference semantics.

- Daniel

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.