C++ Logo

std-proposals

Advanced search

Re: [std-proposals] The syntax of forward and move macros

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Mon, 29 Aug 2022 16:08:35 +0200
pon., 29 sie 2022 o 15:54 Михаил Найденов via Std-Proposals
<std-proposals_at_[hidden]> napisał(a):
>
> I personally think, this should be a minimal-syntax, non-overridable, unary postscript operator that will work for both forward and move, much like cast-to-T&& today
>
> template <typename T> Dog(T&& name) : name(name&&) //< forward
> {}
>
> Name(string&& aName) : name(aName&&) //< move
>
> {
>
> cout << "Rvalue Name constructor." << endl;
>
> }
>
> If there is ambiguity with binary operator &&, the latter is chosen
> template<class T>
> void func(T&& a, int b) {
> a&&-b //< ok, still operator&&(a,-b)
>
> (a&&)-b //< ok, std::forward<T>(a) - b;
> }

Should this be the other way around? `&&a` not `a&&`?
As far I understand this is available in standard but it is used by
computed goto labels in GCC.

>
>
> On Mon, Aug 29, 2022 at 2:31 AM Amar Saric via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> Perfect forwarding received a lot of attention initially when it was first added. By now, everybody should be clear on how it is used and what its purpose is. However, the syntax leaves something to be desired, as the forward template requires a parameter, which is actually not necessary, and frankly a bit ugly. This can be completely avoided by stripping the references and using a macro, as follows:
>>
>>
>>
>> #include <iostream>
>>
>> #include <string>
>>
>> #include <utility>
>>
>>
>>
>>
>>
>> namespace pf
>>
>> {
>>
>> template <typename T> struct check_if_ref
>>
>> {
>>
>> static_assert(std::is_reference<T>::value, "ref_forward needs a reference");
>>
>> typedef T type;
>>
>> };
>>
>> template <typename T> struct _remove_rvalue_reference
>>
>> {
>>
>> typedef T type;
>>
>> };
>>
>> template <typename T> struct _remove_rvalue_reference<T &&>
>>
>> {
>>
>> typedef T type;
>>
>> };
>>
>> template <typename T>
>>
>> using remove_rvalue_reference = typename _remove_rvalue_reference<T>::type;
>>
>> }
>>
>> #define ref_forward(p) (std::forward<pf::\
>>
>> remove_rvalue_reference<typename pf::\
>>
>> check_if_ref<decltype(p)>::type>>(p))
>>
>> #define ref_to_rvalue(p) (std::move(p))
>>
>>
>>
>>
>>
>> using std::cout;
>>
>> using std::endl;
>>
>> using std::string;
>>
>>
>>
>> class Name
>>
>> {
>>
>> public:
>>
>> Name(string& aName) : name(aName)
>>
>> {
>>
>> cout << "Lvalue Name constructor." << endl;
>>
>> }
>>
>>
>>
>> Name(string&& aName) : name(ref_to_rvalue(aName))
>>
>> {
>>
>> cout << "Rvalue Name constructor." << endl;
>>
>> }
>>
>>
>>
>> const string& getName() const { return name; }
>>
>>
>>
>> private:
>>
>> string name;
>>
>> };
>>
>>
>>
>> class Dog
>>
>> {
>>
>> public:
>>
>> template <typename T> Dog(T&& name) : name(ref_forward(name)) {}
>>
>> string getName() const { return name.getName(); }
>>
>>
>>
>> private:
>>
>> Name name;
>>
>> };
>>
>>
>>
>> void print(Dog& dog) { cout << "Dog is " << dog.getName() << endl; }
>>
>>
>>
>> int main()
>>
>> {
>>
>> cout << "Dog(string(\"Fido\"))) - rvalue argument:" << endl;
>>
>> Dog dog(string("Fido"));
>>
>> print(dog);
>>
>>
>>
>> cout << "Dog(\"Lassie\")) - rvalue const char* argument:" << endl;
>>
>> Dog another("Lassie");
>>
>> print(another);
>>
>>
>>
>> string var_name("Woofie");
>>
>> cout << "Dog(var_name) - lvalue argument:" << endl;
>>
>> Dog yetanother(var_name);
>>
>> print(yetanother);
>>
>>
>>
>> return 0;
>>
>> }
>>
>>
>>
>> Output:
>>
>>
>>
>> Dog(string("Fido"))) - rvalue argument:
>>
>> Rvalue Name constructor.
>>
>> Dog is Fido
>>
>> Dog("Lassie")) - rvalue const char* argument:
>>
>> Rvalue Name constructor.
>>
>> Dog is Lassie
>>
>> Dog(var_name) - lvalue argument:
>>
>> Lvalue Name constructor.
>>
>> Dog is Woofie
>>
>>
>>
>> Providing two macros similar to the ones above in a separate header would be nice to have in my opinion and, considering how may other features have been added over time, maybe others will feel the same. One could argue that this is just a matter of taste, but macros are used in other places as well. It is in a nutshell what I originally expected it to look like back in the day – what I personally find intuitive – and no means not cast in stone.
>>
>>
>>
>> Tell me what you think: Just a hack or is it worth it?
>>
>>
>>
>> Best,
>>
>>
>>
>> Amar
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2022-08-29 14:08:47