[boost] [optional] using name boost::in_place -- need your opinion/advice

150 views
Skip to first unread message

Andrzej Krzemienski

unread,
May 30, 2016, 3:47:29 AM5/30/16
to bo...@lists.boost.org
Hi Everyone,
I have stumbled upon a problem that I do not know how to address. I would
like to seek an advice from the people in this list.

I am trying to make boost::optional resemble std::optional (where it is
reasonably easy to achieve). std::optional has this nice and useful
"placement" constructor:

std::optional<std::mutex> m {std::in_place};

std::in_place is a tag type, that instructs std::optional to create an
object using placement-new syntax, from the provided arguments (zero in the
example), without incurring any move construction.

I cannot easily copy 1-to-1 this solution, because in namespace boost name
in_place is reserved for the in-place factories:
http://www.boost.org/doc/libs/1_61_0/libs/utility/in_place_factories.html

I could simply go with a different name for a tag, but something tells me
it would introduce an unnecessary complications for users that want to
migrate from one optional to another. I could hack in-place factories so
that they can also be used as a tag, although, I am not sure it is doable
in a type-safe manner, and if it would not confuse people to have this
boost::in_place do a number of different things.

I could use a different namespace, but again, this might look surprising.I
am a bit torn.

I wonder if anyone here needed to face a similar problem, and if you can
think of an elegant solution.

Thanks,
&rzej

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Andrey Semashev

unread,
May 30, 2016, 5:29:52 AM5/30/16
to bo...@lists.boost.org
On Monday, 30 May 2016 12:13:04 MSK Andrzej Krzemienski wrote:
> Hi Everyone,
> I have stumbled upon a problem that I do not know how to address. I would
> like to seek an advice from the people in this list.
>
> I am trying to make boost::optional resemble std::optional (where it is
> reasonably easy to achieve). std::optional has this nice and useful
> "placement" constructor:
>
> std::optional<std::mutex> m {std::in_place};
>
> std::in_place is a tag type, that instructs std::optional to create an
> object using placement-new syntax, from the provided arguments (zero in the
> example), without incurring any move construction.
>
> I cannot easily copy 1-to-1 this solution, because in namespace boost name
> in_place is reserved for the in-place factories:
> http://www.boost.org/doc/libs/1_61_0/libs/utility/in_place_factories.html

If not the typed in-place factories, you could transform in_place to be a namespace
scope function object and use it as a tag in the optional constructor. The typed in-place
factories ruin the solution though, even if not used by optional.

> I could simply go with a different name for a tag, but something tells me
> it would introduce an unnecessary complications for users that want to
> migrate from one optional to another. I could hack in-place factories so
> that they can also be used as a tag, although, I am not sure it is doable
> in a type-safe manner, and if it would not confuse people to have this
> boost::in_place do a number of different things.
>
> I could use a different namespace, but again, this might look surprising.I
> am a bit torn.

I think that would be the best solution. Additionally, I would suggest moving the whole
library to its own namespace (e.g. optionals). Then the tag in the library namespace
would look more natural. For backward compatibility you could import the optional class
template into boost namespace.

Vladimir Batov

unread,
May 30, 2016, 6:05:11 AM5/30/16
to bo...@lists.boost.org
Andrzej,

On 2016-05-30 17:47, Andrzej Krzemienski wrote:
> ...
> I am trying to make boost::optional resemble std::optional (where it is
> reasonably easy to achieve). std::optional has this nice and useful
> "placement" constructor:
>
> std::optional<std::mutex> m {std::in_place};
>
> std::in_place is a tag type, that instructs std::optional to create an
> object using placement-new syntax, from the provided arguments (zero in
> the
> example), without incurring any move construction.
> ...

To me the situation sounds quite concerning as I'd expect boost libs to
extend std counterparts, i.e. I suspect many people would expect
boost::foo = std::foo + something-else-useful functionally-wise. That
is, I'd personally expect the migration from boost::foo to std::foo to
be a simple renaming matter (if I did not use extra boost
functionality).

The situation with in-place factories sounds like a diversion and you
seem to suggest (if I've got it right) to move even further.

Would not it be long-term proper to align boost::optional with
std::optional? If that requires renaming boost in-place factories, then
that might be a better long-term solution. If, say, that additional
functionality is later scheduled for std inclusion.

Krzysztof Czainski

unread,
May 30, 2016, 6:30:57 AM5/30/16
to Boost developers
2016-05-30 11:29 GMT+02:00 Andrey Semashev <andrey....@gmail.com>:

> On Monday, 30 May 2016 12:13:04 MSK Andrzej Krzemienski wrote:
> > Hi Everyone,
> > I have stumbled upon a problem that I do not know how to address. I would
> > like to seek an advice from the people in this list.
> >
> > I am trying to make boost::optional resemble std::optional (where it is
> > reasonably easy to achieve). std::optional has this nice and useful
> > "placement" constructor:
> >
> > std::optional<std::mutex> m {std::in_place};
> >
> > std::in_place is a tag type, that instructs std::optional to create an
> > object using placement-new syntax, from the provided arguments (zero in
> the
> > example), without incurring any move construction.
> >
> > I cannot easily copy 1-to-1 this solution, because in namespace boost
> name
> > in_place is reserved for the in-place factories:
> >
> http://www.boost.org/doc/libs/1_61_0/libs/utility/in_place_factories.html
>
> If not the typed in-place factories, you could transform in_place to be a
> namespace
> scope function object and use it as a tag in the optional constructor.

+1


> The typed in-place
> factories ruin the solution though, even if not used by optional.
>
How so?

Andrzej Krzemienski

unread,
May 30, 2016, 6:46:53 AM5/30/16
to bo...@lists.boost.org
2016-05-30 12:04 GMT+02:00 Vladimir Batov <Vladimi...@constrainttec.com>
:

> Andrzej,
>
> On 2016-05-30 17:47, Andrzej Krzemienski wrote:
>
>> ...
>> I am trying to make boost::optional resemble std::optional (where it is
>> reasonably easy to achieve). std::optional has this nice and useful
>> "placement" constructor:
>>
>> std::optional<std::mutex> m {std::in_place};
>>
>> std::in_place is a tag type, that instructs std::optional to create an
>> object using placement-new syntax, from the provided arguments (zero in
>> the
>> example), without incurring any move construction.
>> ...
>>
>
> To me the situation sounds quite concerning as I'd expect boost libs to
> extend std counterparts, i.e. I suspect many people would expect boost::foo
> = std::foo + something-else-useful functionally-wise. That is, I'd
> personally expect the migration from boost::foo to std::foo to be a simple
> renaming matter (if I did not use extra boost functionality).
>
> The situation with in-place factories sounds like a diversion and you seem
> to suggest (if I've got it right) to move even further.
>

There seems to be some misunderstanding here. Indeed, there is currently a
gap between std::optional and boost::optional: we have a name
std::in_place, which is a tag, and we have a name boost::in_place, which is
something different. More, boost::in_place is not part of Boost.Optional
library: it is in Boost Utility Library.

I am exploring the possibility of closing the gap between two optionals, I
just don't see how to do it without breaking the backwards compatibility
for Boost users.


>
> Would not it be long-term proper to align boost::optional with
> std::optional? If that requires renaming boost in-place factories, then
> that might be a better long-term solution.


I read your suggestion as "rename current in-place factories form
boost::in_place to something else". Is that right?


> If, say, that additional functionality is later scheduled for std
> inclusion.


I am not sure what you mean here. I am pretty sure the in-place factories
will never be standardized, as we have a superior solution in C++11: tags
and perfect-forwarding of functions.

Regards,
&rzej

Andrey Semashev

unread,
May 30, 2016, 6:47:15 AM5/30/16
to bo...@lists.boost.org
On Monday, 30 May 2016 13:45:28 MSK Krzysztof Czainski
wrote:
> 2016-05-30 11:29 GMT+02:00 Andrey Semashev
<andrey....@gmail.com>:
>
> > The typed in-place
> > factories ruin the solution though, even if not used by
optional.
>
> How so?

Typed in-place factory requires an explicit template parameter
to be specified, which is not achievable if in_place is an object.

Andrzej Krzemienski

unread,
May 30, 2016, 6:50:18 AM5/30/16
to bo...@lists.boost.org
2016-05-30 11:29 GMT+02:00 Andrey Semashev <andrey....@gmail.com>:

Hmm. Moving optional to a nested namespace has other benefits also:
disabling unintended ADL. But I can't see how I can be made to work for a
tag like in_place.

If I put it also into a nested namespace and then do a:

namespace boost{
using nested::in_place
}

It will still collide with the current in-place factories. Or did I
misunderstand your suggestion?

Regards,
&rzej

Andrey Semashev

unread,
May 30, 2016, 6:58:15 AM5/30/16
to bo...@lists.boost.org
On Monday, 30 May 2016 13:52:20 MSK Andrzej Krzemienski wrote:
> 2016-05-30 11:29 GMT+02:00 Andrey Semashev <andrey....@gmail.com>:
> >
> > I think that would be the best solution. Additionally, I would suggest
> > moving the whole
> > library to its own namespace (e.g. optionals). Then the tag in the library
> > namespace
> > would look more natural. For backward compatibility you could import the
> > optional class
> > template into boost namespace.
>
> Hmm. Moving optional to a nested namespace has other benefits also:
> disabling unintended ADL.

Exactly.

> But I can't see how I can be made to work for a
> tag like in_place.
>
> If I put it also into a nested namespace and then do a:
>
> namespace boost{
> using nested::in_place
> }
>
> It will still collide with the current in-place factories. Or did I
> misunderstand your suggestion?

No, I wasn't suggesting importing boost::optionals::in_place into boost. Only import what
is currently considered API (i.e. the optional template; I don't think anything else qualifies
as such). Also document the change and deprecate the imports so that people start
porting to the nested namespace. You can remove the imports when you feel it's safe.

This could also be done for boost::none as well for good measure.

Andrzej Krzemienski

unread,
May 30, 2016, 7:05:38 AM5/30/16
to bo...@lists.boost.org
But wouldn't that be a bit of an inconvenience that a "vocabulary type" as
common as Optional should be used with additional long namespace prefix (or
users required to type a using declaration themselves everywhere)?

Regards,
&rzej

Andrey Semashev

unread,
May 30, 2016, 7:16:52 AM5/30/16
to bo...@lists.boost.org
I don't find that inconvenient. I would rather have every Boost library in its own
namespace. Name clashes pose much much more inconvenience IMO.

Krzysztof Czainski

unread,
May 30, 2016, 7:22:36 AM5/30/16
to Boost developers
2016-05-30 12:46 GMT+02:00 Andrey Semashev <andrey....@gmail.com>:

> On Monday, 30 May 2016 13:45:28 MSK Krzysztof Czainski
> wrote:
> > 2016-05-30 11:29 GMT+02:00 Andrey Semashev
> <andrey....@gmail.com>:
> >
> > > The typed in-place
> > > factories ruin the solution though, even if not used by
> optional.
> >
> > How so?
>
> Typed in-place factory requires an explicit template parameter
> to be specified, which is not achievable if in_place is an object.
>

Oh yeah. Too bad a variable template cannot be "overloaded" with the
non-template function object.

Krzysztof Czainski

unread,
May 30, 2016, 7:41:09 AM5/30/16
to Boost developers
2016-05-30 13:21 GMT+02:00 Krzysztof Czainski <1cza...@gmail.com>:

> 2016-05-30 12:46 GMT+02:00 Andrey Semashev <andrey....@gmail.com>:
>
>> On Monday, 30 May 2016 13:45:28 MSK Krzysztof Czainski
>> wrote:
>> > 2016-05-30 11:29 GMT+02:00 Andrey Semashev
>> <andrey....@gmail.com>:
>> >
>> > > The typed in-place
>> > > factories ruin the solution though, even if not used by
>> optional.
>> >
>> > How so?
>>
>> Typed in-place factory requires an explicit template parameter
>> to be specified, which is not achievable if in_place is an object.
>>
>
> Oh yeah. Too bad a variable template cannot be "overloaded" with the
> non-template function object.
>

Maybe in_place can be hacked as is without changing it to a function
object? Here's a proof of concept. It compiles [1], so it seems 'in_place'
can be used as a tag with the current implementation of boost::in_place()
overloads.

[1] http://ideone.com/zzbwq4


1. struct in_place_factory0 {};
2.
3. in_place_factory0 in_place() {}
4. template <class T> void in_place(T) {}
5. template <class T, class U> void in_place(T, U) {}
6.
7. void test(in_place_factory0 (&in_place_tag)()) {}
8.
9. int main() {
10. test(in_place);
11. }

Vladimir Batov

unread,
May 30, 2016, 6:31:03 PM5/30/16
to bo...@lists.boost.org
On 05/30/2016 08:46 PM, Andrzej Krzemienski wrote:
> 2016-05-30 12:04 GMT+02:00 Vladimir Batov:
>> Would not it be long-term proper to align boost::optional with
>> std::optional? If that requires renaming boost in-place factories, then
>> that might be a better long-term solution.
> I read your suggestion as "rename current in-place factories form
> boost::in_place to something else". Is that right?

I suspect that might be an unpleasant, unfortunate but essential move as
Boost (or any other lib) IMO cannot possibly be changing,
re-interpreting, re-implementing std concepts. The std lib is the center
of C++ universe so to speak. Everything else are the ripples. If the
"ripples" clash with std, they need to adjust.

If boost::in_place is renamed to, say, in_place_factory, then the user
inconvenience will be minimal with global rename. IMO.

I understand that that might be beyond your boost::optional
task/framework but I feel that'd be the right thing to do for the Boost
ecosystem as a whole.

> ... I am pretty sure the in-place factories
> will never be standardized, as we have a superior solution in C++11: tags
> and perfect-forwarding of functions.

More reasons to do the right thing, i.e. to restore the std conformance.
Reply all
Reply to author
Forward
0 new messages