[isocpp-lib] CH 3, p0032r2 -- let's not have too clever tags
martinmoene opened this issue · 1 comments
Message by Andrzej Krzemienski, 25 Oct 2016, copied here for convenience:
Hi All,
I was recently playing with the new implementation of std::optional (in Clang and in GCC), and found that the following usage does not compile:
#include <cassert>
#include <optional>
using std::optional;
using std::nullopt;
using std::in_place;
int main()
{
optional<optional<optional<int>>> o (in_place, in_place, nullopt);
assert (o);
assert (*o);
assert (!**o);
}
It used to compile with the reference implementation that came with the Optional proposal, though (https://github.com/akrzemi1/Optional).
This use case broke when GCC implemented clever tags from p0032r2. Now in_place
is a reference to function which is overloaded, so deduction fails, and causes the overload resolution to fail. In order to make my example work, I am forced to do explicit casting:
optional<optional<optional<int>>> o (
in_place,
static_cast<std::in_place_t>(in_place),
nullopt
);
This seems to be counter to the idea of tags, which were meant to be:
- easy to use
- clearly state which form of initialization to choose
Please, consider it an additional argument in support of NB comment CH 3.
Also, I offer a more philosophical argument against reusing the same name to mean three slightly different things.
The following two situations are different:
I want an std::variant initialized with its third type active.
I want an std::variant initialized with type S active.
And because they are different I would expect them to be spelled out (slightly) different:
variant<A, B, C> v1 {in_place_type<B>}; // and check if B is one in the set
variant<A, B, C> v2 {in_place_at<2>}; // and check if 2 is within range
This makes sense: different kind of initialization -- different name.
And conversely, we do not seem to gain anything by reusing the same name in different initializations. You cannot make a "syntactic" use of the fact that they are three function overloads.
Regards,
&rzej;