2011-11-29 21 views
12

Si consideri il seguente codice:Soluzione per il contesto nondeduced

#include <iostream> 

template<class T> 
struct outer { 
    struct inner {}; 
}; 

template<class T> 
std::ostream& operator<<(std::ostream & stream, 
         typename outer<T>::inner const& value) { 
    std::cout << "An outer::inner!"; 
    return stream; 
} 

int main() { 
    outer<float>::inner foo; 

    std::cout << foo << std::endl; // does not compile 
} 

Questo non si compila, perché typename outer<T>::inner è un contesto nondeduced (come spiegato here), vale a dire il modello-argomentazione di tipo non può essere dedotto dal compilatore (leggi this answer per il perché). Come la vedo io, ho due opzioni per farlo funzionare:

  1. Spostare inner al di fuori di outer e ne fanno una classe template. Preferisco questo, perché l'impatto sull'uso del codice è minore.
  2. Aggiungere un to_string -metodo interno.

Esistono altre soluzioni per questo (che non comportano una brutta sintassi nell'uso del codice)?

risposta

20

È possibile spostare l'operatore nel corpo della classe interna e inserire friend prima di esso. Quindi sostituire il tipo di parametro con il numero inner.

Un'altra tecnica consiste nel derivare l'interno da una base CRTP parametrizzata dall'interno. Quindi, impostare il parametro per digitare la classe CRTP e inserire il riferimento del parametro sulla classe derivata inner, il cui tipo è fornito dall'argomento del modello che si deduce.

+1

+1 per entrambe le tecniche. Vorrei poter dare +2. – Nawaz

+0

L'approccio 'friend' funziona bene. Non sapevo che è possibile definire una funzione in una dichiarazione 'friend' (per coloro che sono interessati: l'ho appena visto, è definito in §11.4.5 dello standard 2003). –

Problemi correlati