2014-11-18 13 views
10

C'è un altro modo che sovraccaricare manualmente la funzione membro corrispondente e chiamare il primo overload con il membro come argomento?Utilizzo di un membro della classe come argomento predefinito per una funzione membro

sto cercando qualcosa sulla falsariga di

class test 
{ 
    string t1="test"; 

    testfun(string& val = this->t1) 
    { /* modify val somehow */ } 
}; 

(Provatelo: http://goo.gl/36p4CF)

Attualmente immagino non v'è alcuna ragione tecnica per cui questo non dovrebbe funzionare.

  • C'è una soluzione che lo fa in questo modo eccetto il sovraccarico e l'impostazione del parametro manualmente?
  • Perché non funziona, c'è una ragione tecnica per questo?
+0

Basta usare "test" per non ridurre le prestazioni o aumentare l'utilizzo della memoria perché sarà costante. –

+0

@ self: Ma 't1' non è costante; quindi sostituirlo con un valore costante non farà necessariamente la stessa cosa. –

+0

Voglio dire usare la stringa letterale "test" –

risposta

14

[dcl.fct.default]/8:

La parola chiave this non devono essere utilizzati in un argomento di default di una funzione membro.

Questo è un caso speciale di un problema generale: non è possibile fare riferimento ad altri parametri in un argomento predefinito di un parametro. Cioè

void f(int a, int b = a) {} 

È mal formato. E così sarebbe

class A 
{ 
    int j; 
}; 

void f(A* this, int i = this->j) {} 

che è fondamentalmente ciò che il compilatore trasforma una funzione di membro della forma void f(int i = j) {} in. Ciò deriva dal fatto che l'ordine di valutazione degli argomenti di funzione e l'espressione postfix (che costituisce l'argomento dell'oggetto) non è specificato. [dcl.fct.default]/9:

Gli argomenti predefiniti vengono valutati ogni volta che viene richiamata la funzione. L'ordine di valutazione degli argomenti di funzione non è specificato. Di conseguenza, i parametri di una funzione non devono essere utilizzati in un argomento predefinito , anche se non vengono valutati.

+0

Sì, vedo il problema. Ma lo zucchero sintattico sarebbe bello;) –

+0

@thigg Non posso negarlo. : D Nel tuo caso i sovraccarichi dovrebbero fare il lavoro con una ragionevole leggibilità. – Columbo

+0

Sì, ma devo farlo per un paio di funzioni, quindi è fastidioso;) –

1

Non hai detto quello che vuoi raggiungere. Suppongo che tu abbia bisogno che ciascuna delle tue istanze reagisca in un modo specifico, a seconda di una determinata variabile di classe.

Tuttavia, se non è necessario un comportamento per istanza, è possibile utilizzare variabili statiche. Le seguenti opere:

#include <iostream> 
using namespace std; 
struct test { 
    static string t1; 
    void say(const string &val=t1){ 
    cout << val << "!" << endl; 
    } 
}; 

string test::t1; 

int main() { 
    cout << "Hello World" << endl; 
    test::t1 = string("asd"); 
    test a; 
    a.say(); 
    a.say("bla"); 
    test::t1 = string("blahblah"); 
    a.say(); 
    return 0; 
} 

... il che significa che tutti gli oggetti della classe test useranno la stringa statica t1 come il loro valore di default.

È possibile "hack" un po ', e utilizzare questo come un brutto sentinella:

void say(const string &val=t1){ 
    if (&val == &t1) { 
     // They are using the default value, so act as you want 
    } else { 
     // they are providing a value 
    } 
    } 
+0

Ma è statico –

+1

@thigg Disclaimer: Non hai detto cosa vuoi ottenere. Sì, non riuscivo a capire quali erano le tue esigenze, e volevo solo dare qualche idea su '' static'' vs non. Ok, modificherò un po 'la mia risposta, ma penso che rimanga remoto come utile per le persone che raggiungono la tua domanda. – MariusSiuram

+1

Sì, forse è buono per le persone che stanno cercando. Nel complesso, immagino che questo sia molto istruttivo. –

1

C'è una soluzione facendo in questo modo, tranne il sovraccarico e impostando il parametro manualmente?

No, è necessario un sovraccarico se si desidera che un argomento predefinito dipenda da un altro parametro, incluso this. Anche se, in questo caso, non ha senso poiché si tratta di un costruttore, e t1 non esiste prima che venga chiamato.

Perché non funziona, c'è un motivo tecnico per questo?

Poiché l'ordine di valutazione degli argomenti di funzione non è specificato. Per consentire i valori dei parametri negli argomenti predefiniti, sono necessarie regole molto più complesse per garantire che ciascun parametro sia stato inizializzato prima di essere utilizzato.

Problemi correlati