Date: Mon, 22 Nov 2021 15:16:13 -0500
I think this is the first designated initializer proposal that has a
solution to variadic template forwarding. It's a hideously ugly
solution requiring changing template parameters on functions and
adding a new keyword. But props for taking the problem seriously.
I feel like the main problem with the variadic forwarding issue could
be eliminated if `std::forward` weren't a thing. That is, if there was
some kind of operator that *explicitly* meant "forward this
parameter", this operator could also automatically throw in designated
names for each argument if the forwarding operator were used in a
place that allows designated names. Obviously if you're forwarding
something that isn't the name of a parameter, it wouldn't work.
So maybe this "fwdarg" keyword could be used that way. So
`make_unique` just becomes:
```
template<typename _Tp, typename... _Args>
inline typename _MakeUniq<_Tp>::__single_object
make_unique(_Args&&... __args)
{
return unique_ptr<_Tp>(
new _Tp(fwdarg(__args)...)
);
}
```
Note that a variadic parameter pack in the function declaration
doesn't need special syntax to say "I take designated initializers
too". That should just be how variadic parameter packs work: if you
provide designated arguments to them, the pack captures those
designators. The designators are used in a pack expansion *only* if
you explicitly use the keyword `fwdarg` on the pack.
Note also that this is just an off-the-cuff suggestion. I haven't
thought about it enough to be sure this is a good idea, so feel free
to change any and all of the above rules.
But the main point is that `fwdarg` would solve two problems: the
needlessly wordy `std::forward` and hooking designated argument names
to function calls that want to pass them through. It even has a good
backwards compatibility story, as you can `#define FWDARG(arg)` as
either `std::forward<decltype(arg)>(arg)` or `fwdarg(arg)` based on
the C++ version.
solution to variadic template forwarding. It's a hideously ugly
solution requiring changing template parameters on functions and
adding a new keyword. But props for taking the problem seriously.
I feel like the main problem with the variadic forwarding issue could
be eliminated if `std::forward` weren't a thing. That is, if there was
some kind of operator that *explicitly* meant "forward this
parameter", this operator could also automatically throw in designated
names for each argument if the forwarding operator were used in a
place that allows designated names. Obviously if you're forwarding
something that isn't the name of a parameter, it wouldn't work.
So maybe this "fwdarg" keyword could be used that way. So
`make_unique` just becomes:
```
template<typename _Tp, typename... _Args>
inline typename _MakeUniq<_Tp>::__single_object
make_unique(_Args&&... __args)
{
return unique_ptr<_Tp>(
new _Tp(fwdarg(__args)...)
);
}
```
Note that a variadic parameter pack in the function declaration
doesn't need special syntax to say "I take designated initializers
too". That should just be how variadic parameter packs work: if you
provide designated arguments to them, the pack captures those
designators. The designators are used in a pack expansion *only* if
you explicitly use the keyword `fwdarg` on the pack.
Note also that this is just an off-the-cuff suggestion. I haven't
thought about it enough to be sure this is a good idea, so feel free
to change any and all of the above rules.
But the main point is that `fwdarg` would solve two problems: the
needlessly wordy `std::forward` and hooking designated argument names
to function calls that want to pass them through. It even has a good
backwards compatibility story, as you can `#define FWDARG(arg)` as
either `std::forward<decltype(arg)>(arg)` or `fwdarg(arg)` based on
the C++ version.
Received on 2021-11-22 14:16:25