2011-10-31 10 views
6

tl; dr: Come si fa a perfect forwarding in D?Inoltro perfetto in D?


Il collegamento ha una grande spiegazione, ma per esempio, diciamo che ho questo metodo:

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

Come posso creare un altro metodo, bar(), che può essere chiamato in luogo di foo(), che successivamente chiama "perfettamente" foo() (cioè senza introdurre problemi di compilazione/scope/etc sul sito di chiamata)?

L'approccio naive

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

ovviamente non funziona perché non gestisce il ref, in, out, inout, il const -ness del metodo, pure -ity, nothrow, ecc ... e limita anche come i valori possono essere usati con valori r.

E non so come gestire quei casi possibili ... qualche idea?

risposta

3

Il tuo approccio ingenuo può essere migliorato, anche se non è ancora perfetto:

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

Ora l'unico problema è scope argomenti.

+1

Aspetta, per quanto riguarda 'nothrow',' pure', 'const',' inout', '@ property',' @ safe' e tutte quelle altre cose a cui non riesco a pensare al momento? Ognuno di questi (anche '@ property') può modificare leggermente il comportamento del codice e/o impedire la compilazione. – Mehrdad

+1

Hai bisogno di un auto ref come ritorno, e un se si considera il tuo template, e ancora, non sono sicuro che sia abbastanza. – deadalnix

+0

@Mehrdad: punti buoni, anche se al giorno d'oggi si deduce puro per i modelli. – dsimcha