Isso não é permitido pelo texto do padrão e por várias implementações importantes, conforme observado nos comentários, mas por razões completamente não relacionadas.
Primeiro, a razão "pelo livro": o ponto de instanciação de A<C>é, de acordo com o padrão, imediatamente antes da definição deB , e o ponto de instanciação de std::is_default_constructible<C>imediatamente antes disso:
Para uma especialização de modelo de classe, [...] se a especialização é implicitamente instanciada porque é referenciada em outra especialização de modelo, se o contexto do qual a especialização é referenciada depende de um parâmetro de modelo e se a especialização não é instanciada anteriormente para a instanciação do modelo anexo, o ponto de instanciação é imediatamente anterior ao ponto de instanciação do modelo anexo. Caso contrário, o ponto de instanciação para essa especialização precede imediatamente a declaração ou definição do escopo do espaço para nome que se refere à especialização.
Como Cé claramente incompleto nesse ponto, o comportamento da instanciação std::is_default_constructible<C>é indefinido. No entanto, consulte a edição principal 287 , que mudaria essa regra.
Na realidade, isso tem a ver com o NSDMI.
- Os NSDMIs são estranhos porque são atrasados na análise - ou, na linguagem padrão, são um "contexto de classe completa".
- Portanto, isso
= 0poderia, em princípio, se referir a coisas Bainda não declaradas, portanto a implementação não pode realmente tentar analisá-la até que termine B.
- A conclusão de uma classe requer a declaração implícita de funções-membro especiais, em particular o construtor padrão, pois
Cnão há um construtor declarado.
- Partes dessa declaração (consexpr-ness, noexcept-ness) dependem das propriedades do NSDMI.
- Portanto, se o compilador não puder analisar o NSDMI, não poderá concluir a classe.
- Como resultado, no momento em que instancia
A<C>, ele pensa que Cestá incompleto.
Toda essa área que lida com regiões com atraso de análise é lamentavelmente subespecificada, com as divergências na implementação. Pode demorar um pouco antes de ser limpo.