2015-09-09 15 views
8

È il seguente legale?auto-riferimento di classe (o struct) per modello

template< typename T > 
struct tree_node 
    { 
    T t; 
    std::vector<tree_node> children; 
    }; 

Un commento a this post sembra suggerire che non è.


MODIFICA: Questo non mi sembra un tipo di scenario "comportamento indefinito". La semantica prevista non è ambigua. Se si tratta di un uso non valido di un tipo incompleto, dovrebbe essere un errore in fase di compilazione.

In my tests questo sembra funzionare bene (ho usato sia GCC e Clang - entrambi con -Wall -Werror -std=c++11).

C'è qualcosa nella definizione della lingua (precedente a C++ 17) che specifica direttamente o indirettamente questo comportamento non definito, oppure è solo sotto-specificato?


Tenete a mente che questo è molto simile, strutturalmente, a qualcosa di simile al seguente:

typedef int T; 
struct tree_node; 

struct tree_node 
    { 
    T t; 
    tree_node * children; 
    } 
+1

Possibile dupliucato: http://stackoverflow.com/questions/31345193/how-can-an-incomplete-type-be-used-as-a-template-parameter-to-vector-here – NathanOliver

+0

L'eccezione per shared_ptr "mi fa male: https://stackoverflow.com/a/31347287/86967 – nobar

+0

Nella peggiore delle ipotesi, potresti usare' shared_ptr 'invece di solo' tree_node'. – nobar

risposta

9

In realtà, a causa di N4371 abbiamo (da N4527, [vector.overview], sarà in C++ 17):

Un tipo incompleto T può essere utilizzato quando si crea un'istanza vettore se l'allocatore soddisfa la completezza allocatore requisiti 17.6.3.5.1. T deve essere completato prima che venga fatto riferimento a qualsiasi membro della specializzazione risultante del vettore .

Prima di questo, vector non potrebbe essere costruito con un tipo incompleto (che tree_node è a quel punto), e che sarebbe comportamento indefinito.