2015-02-18 16 views
5

In C++, la semantica speciale è operator->, nel senso che se il tipo restituito non è un puntatore, chiamerà di nuovo operator-> su quel tipo. Ma il valore intermedio viene mantenuto come temporaneo dall'espressione chiamante. Questo consente al codice di rilevare variazioni del valore restituito:Inserisci trasparente nello scope del chiamante

template<class T> 
class wrapper 
{ 
    // ... 
    T val; 

    struct arrow_helper 
    { 
     arrow_helper(const T& temp) 
      : temp(temp){} 
     T temp; 
     T* operator->() { return &temp; } 
     ~arrow_helper() { std::cout << "modified to " << temp << '\n'; } 
    }; 

    arrow_helper operator->() { return{ val }; } 
    //return const value to prevent mistakes 
    const T operator*() const { return val; } 
} 

e poi i membri T 's si può accedere in modo trasparente:

wrapper<Foo> f(/*...*/); 
f->bar = 6; 

C'è qualcosa che potrebbe andare male di fare questo? Inoltre, c'è un modo per ottenere questo effetto con funzioni diverse da operator->?

EDIT: Un altro problema che ho incontrato è nelle espressioni come

f->bar = f->bar + 6; 

da quando il arrow_helper dalla seconda operator-> è distrutto ri-sovrascrive il valore di nuovo all'originale. La mia soluzione semi-elegante è per arrow_helper per avere un T orig nascosto e assert(orig == *owner) nel distruttore.

risposta

3

Non v'è alcuna garanzia che saranno catturati tutti i cambiamenti:

Foo &x = f->bar; 
x = 6; /* undetected change */ 
+0

Buon punto, anche se considerando [questo] (http://stackoverflow.com/q/9527820/603688) non sono sicuro se c'è un modo per evitare che oltre a un commento che dice di non farlo. Penso che questo finisca anche per essere UB perché ti riferisci ad un temporaneo che è stato distrutto. – Dan

0

Se non v'è alcun modo per afferrare un riferimento ai suoi dati all'interno T attraverso l'interfaccia 's T o in altro modo, credo che questo dovrebbe essere al sicuro . Se c'è un modo per afferrare un tale puntatore o riferimento, sei fatto e in un comportamento indefinito non appena qualcuno salva tale riferimento e lo usa in un secondo momento.

Problemi correlati