Частичная специализация шаблона класса в производном классе влияет на базовый класс - PullRequest
2 голосов
/ 12 сентября 2009

У меня есть метафункция:

struct METAFUNCION
{
  template<class T>
  struct apply
  {
    typedef T type;
  };
};

Затем я определяю помощника:

template<class T1, class T2>
struct HELPER
{
};

И затем у меня есть вторая метафункция, которая вытекает из приведенной выше метафункции и определяет частичную специализацию применения структуры:

struct METAFUNCION2 : METAFUNCION
{
  template<class T1, class T2>
  struct apply<HELPER<T1, T2> > : METAFUNCION::apply<T2>
  {
  };
};

Пока все хорошо - код компилируется под g ++ 4.3.2. Так что я использовал это как показано ниже:

#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);
}

Выход:

int
double
double

Это меня немного удивило, как я и ожидал:

int
HELPER<float, double>
double

Теперь я знаю, что код, подобный приведенному выше, не компилируется в Microsoft Visual C ++ 2008 (я не помню сообщения, но это было что-то похожее на то, что я не могу специализировать apply struct внутри структуры METAFUNCTION2) * 1019

Итак, мой вопрос - это поведение g ++ соответствует стандарту? У меня сильное чувство, что здесь что-то не так, но я не уверен на 100%.


Для любопытных - у меня такое поведение, которое я ожидал, когда переопределяю METAFUNCTION2 следующим образом:

struct METAFUNCION2 : METAFUNCION
{
  template<class T>
  struct apply : METAFUNCION::apply<T>
  {
  };
  template<class T1, class T2>
  struct apply<HELPER<T1, T2> > : METAFUNCION::apply<T2>
  {
  };
};

Ответы [ 2 ]

3 голосов
/ 12 сентября 2009

Итак, я подал ошибку на gcc

2 голосов
/ 12 сентября 2009

Следующий код недопустим:

struct METAFUNCION2 : METAFUNCION
{
  template<class T1, class T2>
  struct apply<HELPER<T1, T2> > : METAFUNCION::apply<T2>
  {
  };
};

Согласно стандарту C ++ 14.7.3 / 3:

Объявление шаблона функции или шаблона класса, являющегося явно специализированным, должно находиться в области действия на точка объявления явной специализации.

РЕДАКТИРОВАТЬ: В соответствии с Основная проблема 727 это ограничение не распространяется на частичные специализации шаблонов элементов.

...