Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perfect forwarding in D?

tl;dr: How do you do perfect forwarding in D?


The link has a great explanation, but for example, let's say I have this method:

void foo(T)(in int a, out int b, ref int c, scope int delegate(ref const(T)) d)
    const nothrow
{
}

How do I create another method, bar(), which can be called in lieu of foo(), which subsequently calls foo() "perfectly" (i.e. without introducing compilation/scope/etc. problems at the calling site)?

The naive approach

auto bar(T...)(T args)
{
    writeln("foo() intercepted!");
    return foo(args);
}

of course doesn't work because it doesn't handle the ref, in, out, inout, the const-ness of the method, pure-ity, nothrow, etc... and it also limits how the values can be used with r-values.

And I don't know how to handle those possible cases... any ideas?

like image 976
user541686 Avatar asked Oct 31 '11 00:10

user541686


People also ask

What is perfect forwarding?

Perfect forwarding allows a template function that accepts a set of arguments to forward these arguments to another function whilst retaining the lvalue or rvalue nature of the original function arguments.

When should I use std forward?

We use std::forward to retrieve the original value category. If for the handler we provided an rvalue then insert will move from it. If for the handler we provided an lvalue then insert will copy it. There are a lot of rules that come into play for the initial deceivingly simple code.

What is std :: forward C++?

The std::forward function as the std::move function aims at implementing move semantics in C++. The function takes a forwarding reference. According to the T template parameter, std::forward identifies whether an lvalue or an rvalue reference has been passed to it and returns a corresponding kind of reference.

What is lvalue and rvalue in C++?

An lvalue (locator value) represents an object that occupies some identifiable location in memory (i.e. has an address). rvalues are defined by exclusion. Every expression is either an lvalue or an rvalue, so, an rvalue is an expression that does not represent an object occupying some identifiable location in memory.


1 Answers

Your naive approach can be improved upon, though it's still not perfect:

auto ref bar(T...)(auto ref T args)
{
    writeln("foo() intercepted!");
    return foo(args);
}

Now the only problem is scope arguments.

like image 55
dsimcha Avatar answered Oct 28 '22 00:10

dsimcha