显式模板实例化在XLC上提供编译错误,但适用于其他编译器

时间:2013-02-04 16:57:48

标签: c++ implementation c++03 xlc

以下代码是我尝试为客户端要求实现的功能的简化最小版本。

它无法在IBM的XLC编译器(版本9和11,两者)上编译,错误为A non-type template parameter cannot have type "int X::*".。但是,我使用g ++ 4.7.2,clang ++ 3.2和Intel-13.0尝试了相同的代码,并且它们已成功编译。

我很想知道XLC是否是这里唯一合理的声音,还是其他编译器是否正确?

struct X {
    X() : y(123) {}
    int y;
};

struct XFoo {
   typedef int X::* Type;
};

template <typename Name, typename Name::Type value>
struct Bar {
    typename Name::Type getValue(Name) {
        return value;
    }
};

template class Bar<XFoo, &X::y>;    // xlc error here, works fine on others

int main() {}

我多次阅读关于模板的C ++ 2003标准章节,并且无法最终找到禁止使用<type> <class>::*作为非模板类​​型的内容。我已经在SO和搜索引擎中搜索了一些解释,但没有遇到任何权威来源,这有助于我做出决定。

我知道这可能不是一个好的编码实践,但这是客户端代码所必需的,因为它们的要求有些独特。我也尝试了其他各种替代方案,但它对他们没有用。

2 个答案:

答案 0 :(得分:1)

明确允许指向成员的模板参数,XLC应该提供错误报告。

答案 1 :(得分:1)

§14.1/ 4的C ++ 03标准允许将成员指针作为模板参数:

  

非类型模板参数应具有以下(可选的cv限定)类型之一:

     
      
  • 整数或枚举类型,
  •   
  • 指向对象或指向函数的指针,
  •   
  • 引用对象或对函数的引用,
  •   
  • 指向会员的指针
  •   

相应地,根据§14.3.2/ 1:

  

非类型,非模板模板参数的模板参数应为 之一:

     
      
  • 整数或枚举类型的整数常量表达式;或
  •   
  • 非类型模板参数的名称;或
  •   
  • 具有外部链接的对象或函数的地址,包括函数模板和函数template-id,但不包括非静态类成员,表示为&amp; id-expression其中&amp;如果名称引用函数或数组,或者相应的template-parameter是引用,则是可选的;或
  •   
  • 指向成员的指针,如5.3.1
  • 中所述   

因此,非类型模板参数可以成为成员的指针。有一些限制适用于模板专业化,但在这种情况下它们似乎不适用。