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>
  {
  };
};
Foi útil?

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top