especialização parcial de um modelo de classe em classe derivada afecta classe base
-
06-07-2019 - |
Pergunta
Eu tenho um metafunção:
struct METAFUNCION
{
template<class T>
struct apply
{
typedef T type;
};
};
Então eu definir um auxiliar:
template<class T1, class T2>
struct HELPER
{
};
e, em seguida, I têm segundo metafunção que deriva do metafunção acima e define especialização parcial de aplicar estrutura:
struct METAFUNCION2 : METAFUNCION
{
template<class T1, class T2>
struct apply<HELPER<T1, T2> > : METAFUNCION::apply<T2>
{
};
};
Até agora, tão bom - os compila código sob g ++ 4.3.2. Então eu usei-o como abaixo:
#include <typeinfo>
#include <string>
#include <cstdlib>
#include <cxxabi.h>
template<typename T>
struct type_info2
{
static std::string name()
{
char *p = abi::__cxa_demangle(typeid(T).name(), 0, 0, 0);
std::string r(p);
free(p);
return(r);
}
};
#include <boost/mpl/apply.hpp>
#include <iostream>
int main()
{
std::cout <<
type_info2<boost::mpl::apply<METAFUNCION, int>::type>::name() <<
std::endl;
std::cout <<
type_info2<boost::mpl::apply<METAFUNCION, HELPER<float, double> >::type>::name() <<
std::endl;
std::cout <<
type_info2<boost::mpl::apply<METAFUNCION2, HELPER<float, double> >::type>::name() <<
std::endl;
return(0);
}
A saída:
int
double
double
Isso me surpreendeu um pouco como eu esperava:
int
HELPER<float, double>
double
Agora, eu sei que um código como acima não compilar em Microsoft Visual C ++ 2008 (eu não lembre a mensagem, mas era algo ao longo das linhas que eu não pode se especializar aplicar struct dentro METAFUNCTION2 struct).
Assim, a minha pergunta é - é este g ++ comportamento conformant com o padrão? Eu tenho um forte sentimento de que há algo errado aqui, mas não estou 100% de certeza.
Para os curiosos - Tenho a behaviuor como eu esperava quando eu redefinir METAFUNCTION2 desta maneira:
struct METAFUNCION2 : METAFUNCION
{
template<class T>
struct apply : METAFUNCION::apply<T>
{
};
template<class T1, class T2>
struct apply<HELPER<T1, T2> > : METAFUNCION::apply<T2>
{
};
};
Solução
O código a seguir é ilegal:
struct METAFUNCION2 : METAFUNCION
{
template<class T1, class T2>
struct apply<HELPER<T1, T2> > : METAFUNCION::apply<T2>
{
};
};
De acordo com a C ++ Padrão 14.7.3 / 3:
A declaração de um modelo de função ou modelo de classe que está sendo explicitamente especializada deve estar no escopo no ponto de declaração de uma especialização explícita.
EDIT: De acordo com o Núcleo Issue 727 esta restrição não se aplica a especializações parciais de modelos de membro.
Outras dicas
Então eu arquivado um bug no gcc