C ++ Template Metaprogramming e Call By Need Valutazione

1

Recentemente ho scritto una meta funzione C ++ piuttosto complessa che si riduce a:

template <size_t N, typename val>
struct Rec {
    using type = typename std::conditional<N == 0,
        val,
        typename Rec<N - 1, val>::type>::type;
};

Sia Clang che G ++ barf su questo tipo di recessione, affermando che, "La profondità di istanziazione del template supera il massimo di X". Ho riscritto rapidamente il programma e risolto il problema, ma mi ha fatto riflettere sulla strategia di valutazione dei parametri del modello C ++.

C'è qualcosa nello standard C ++ che impedirebbe ai template di utilizzare la chiamata in base alla necessità di valutare i parametri del modello, o questa limitazione è puramente un difetto di implementazione?

    
posta Matt Bierner 17.01.2015 - 22:20
fonte

1 risposta

5

Per istanziare std::conditional<N==0, val, typename Rec<N-1, val>::type> , il compilatore deve dimostrare che sia val che Rec<N-1, val>::type valutano un tipo e che N==0 valuta un'espressione costante che può essere utilizzata in un contesto booleano.
Se tali condizioni non sono soddisfatte, il programma non è ben formato e richiede una diagnostica.

È anche solo dopo aver valutato gli argomenti del template che il compilatore può iniziare a cercare le specializzazioni che corrispondono, perché per tutto il compilatore sa, potrebbe esserci una specializzazione di std::conditional per i parametri true , val , Rec<-1,val>::type più specializzato di quello predefinito per std::conditional<true, T, F> .
Questo è anche il motivo per cui hai bisogno di una specializzazione di Rec per fermare la ricorsione: la condizione usata in std::conditional è solo controllata dopo la ricorsione ha fatto il suo corso e ha colpito una condizione di chiusura.

Il compilatore sarebbe perfettamente felice se avessi aggiunto la specializzazione

template <class val>
class Rec<-42, val> {
  typedef void type;
};

e darti i risultati attesi (anche se val! = void).

    
risposta data 18.01.2015 - 12:29
fonte

Leggi altre domande sui tag