Boost logo

Boost :

Subject: Re: [boost] [optional] operator<(optional<T>, T) -- is it wrong?
From: Vladimir Batov (Vladimir.Batov_at_[hidden])
Date: 2014-11-23 20:59:32


On 11/21/2014 09:29 PM, Andrzej Krzemienski wrote:
> ...

> (1) In C++ we have the converting constructor. This appears close to
> what you call "bringing T into the optional<T> land", but I claim it
> is not the same.

They are obviously not the same -- "bringing" is an action, "converting
constructor" is the tool to execute that action... when needed. If we
have the tool (the constructor) it does not mean we swing it
indiscriminately and apply it everywhere it fits. There has to be
logical justification to apply that constructor... not just mechanical
ability to do that. The converter is a powerful tool. However, with that
"hammer" we should not fall into the trap of seeing everything like a nail.

> And the consequences of these nuance differences result in the problem
> in question.

To me the difference's not that "nuanced". "Action" and "tool" are like
"walking" and "shoes", "singing" and "microphone".

> Perhaps the notion of "bringing T into the optional<T> land" would be
> better reflected by an explicit constructor, or function make_optional().

Mechanically, yes. Logically I am sure there are places where the action
(of T to optional<T>) is unequivocal. If my API requests optional<T>,
then I explicitly say -- I deal with optional<T> and apply optional<T>
rules. I.e. my API is in the optional<T> land. So, when you provide T
instead, it's propagated to optional<T> at the point of entering my API.
The same as feed 'int' to func(double). It's not controversial, is it?
How func(optional<T>) is different?

> I am not saying that the converting constructor is wrong here. I am
> just saying that the motivation is *slightly* different than "bringing
> T into the optional<T> land", it is more for syntactic convenience,
> which is almost the same, but not same. (2) Your philosophy "when the
> direction of conversion is not as clear, we refuse applying it" --
> there is no way to apply it within the definition of optional. We can
> apply it by poisoning every operation in the world that takes T or
> optional<T>. But that looks impractical. Back to Vicente's concern:
> User defining its own function
>> void f(optional<T>, optional<T>);
>>
>> would need to add the following?
>>
>> void f(T, optional<T>) { BOOST_STATIC_ASSERT(); }
>> void f(optional<T>, T) { BOOST_STATIC_ASSERT(); }
>>
>> What if there are 3 optional parameters? We can not say to the user that
>> they need to program this way.

IMO no need complicating the matter with number of parameters. Just one
will do. Are you implying that for every

void f(optional<T>);

we need to have poisoned

void f(T) { BOOST_STATIC_ASSERT(); }

As I tried to describe above, if I specify "void f(optional<T>,
optional<T>);" as my API, then I explicitly say that it plays by
optional<T> rules. It's no different from "void f(double, double);"
called with "ints". If playing be optional<T> rules might be different
for T rules or potentially confusing, I suggest we poison it. op<(T,
optional<T>) is an excellent example because it implements interaction
of its two arguments and that interaction s different if

1) both args are T;
2) both args are optional<T>;
3) args are of different types.

As they are different, we should have 3 different implementations... #3
just happens to be no-implementation.

I might well fail to understand your concern as those examples above
seem far too hypothetical. If you can come up with a realistic example,
that'd probably help me to see what you see.

> I do not think it has been addressed.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk