0

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

它无法在 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 和搜索引擎搜索了解释,但没有遇到任何可以帮助我做出决定的权威来源。

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

4

2 回答 2

1

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

于 2013-02-04T17:19:16.767 回答
1

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

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

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

相应地,根据 § 14.3.2/1:

非类型、非模板模板参数的模板参数应为以下之一

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

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

于 2013-02-04T17:19:34.030 回答