以下代码是我尝试为客户端要求实现的功能的简化最小版本。
它无法在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和搜索引擎中搜索了一些解释,但没有遇到任何权威来源,这有助于我做出决定。
我知道这可能不是一个好的编码实践,但这是客户端代码所必需的,因为它们的要求有些独特。我也尝试了其他各种替代方案,但它对他们没有用。
答案 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 。
中所述
因此,非类型模板参数可以成为成员的指针。有一些限制适用于模板专业化,但在这种情况下它们似乎不适用。