forward

Forwards function arguments while keeping out, ref, and lazy on the parameters.

template forward (
args...
) {}

Parameters

args

a parameter list or an std.meta.AliasSeq.

Return Value

An AliasSeq of args with out, ref, and lazy saved.

Examples

class C
{
    static int foo(int n) { return 1; }
    static int foo(ref int n) { return 2; }
}

// with forward
int bar()(auto ref int x) { return C.foo(forward!x); }

// without forward
int baz()(auto ref int x) { return C.foo(x); }

int i;
assert(bar(1) == 1);
assert(bar(i) == 2);

assert(baz(1) == 2);
assert(baz(i) == 2);
void foo(int n, ref string s) { s = null; foreach (i; 0 .. n) s ~= "Hello"; }

// forwards all arguments which are bound to parameter tuple
void bar(Args...)(auto ref Args args) { return foo(forward!args); }

// forwards all arguments with swapping order
void baz(Args...)(auto ref Args args) { return foo(forward!args[$/2..$], forward!args[0..$/2]); }

string s;
bar(1, s);
assert(s == "Hello");
baz(s, 2);
assert(s == "HelloHello");
1 struct X {
2     int i;
3     this(this)
4     {
5         ++i;
6     }
7 }
8 
9 struct Y
10 {
11     private X x_;
12     this()(auto ref X x)
13     {
14         x_ = forward!x;
15     }
16 }
17 
18 struct Z
19 {
20     private const X x_;
21     this()(auto ref X x)
22     {
23         x_ = forward!x;
24     }
25     this()(auto const ref X x)
26     {
27         x_ = forward!x;
28     }
29 }
30 
31 X x;
32 const X cx;
33 auto constX = (){ const X x; return x; };
34 static assert(__traits(compiles, { Y y = x; }));
35 static assert(__traits(compiles, { Y y = X(); }));
36 static assert(!__traits(compiles, { Y y = cx; }));
37 static assert(!__traits(compiles, { Y y = constX(); }));
38 static assert(__traits(compiles, { Z z = x; }));
39 static assert(__traits(compiles, { Z z = X(); }));
40 static assert(__traits(compiles, { Z z = cx; }));
41 static assert(__traits(compiles, { Z z = constX(); }));
42 
43 
44 Y y1 = x;
45 // ref lvalue, copy
46 assert(y1.x_.i == 1);
47 Y y2 = X();
48 // rvalue, move
49 assert(y2.x_.i == 0);
50 
51 Z z1 = x;
52 // ref lvalue, copy
53 assert(z1.x_.i == 1);
54 Z z2 = X();
55 // rvalue, move
56 assert(z2.x_.i == 0);
57 Z z3 = cx;
58 // ref const lvalue, copy
59 assert(z3.x_.i == 1);
60 Z z4 = constX();
61 // const rvalue, copy
62 assert(z4.x_.i == 1);

Meta