代码之家  ›  专栏  ›  技术社区  ›  Tomek

派生类中类模板的部分专用化会影响基类

  •  2
  • Tomek  · 技术社区  · 15 年前

    我有一个元函数:

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

    然后我定义一个助手:

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

    然后我还有第二个元函数,它从上面的元函数派生,并定义了apply结构的部分专门化:

    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
    

    现在,我知道上面的代码没有在微软Visual C++ 2008中编译(我不记得这个消息,但是它是我不能专心在Meta函数结构中应用Struts的东西)。

    所以我的问题是-这个g++行为符合标准吗?我有一种强烈的感觉,这里有什么问题,但我不是100%肯定。


    好奇的是,当我用这种方式重新定义元函数2时,我有我所期望的行为:

    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 回复  |  直到 15 年前
        1
  •  2
  •   Kirill V. Lyadvinsky    15 年前

    以下代码是非法的:

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

    根据C++标准147.3/3:

    明确专门化的函数模板或类模板的声明应在 明确专门化的声明点。

    编辑: 根据 Core Issue 727 此限制不适用于成员模板的部分专用化。

        2
  •  3
  •   Tomek    15 年前

    所以我提出 a bug on gcc