使用指向数据成员的指针作为非类型模板参数

时间:2016-02-14 22:35:49

标签: c++ templates

我想知道阻止指向数据成员的指针被用作非类型模板参数的基本原理,如[temp.arg.nontype]中所述:

  

[注意:数组元素或非静态数据成员的地址不是   可接受的模板参数。 [snip] - 结束说明]

此外,cppreference.com says that指向数据成员的指针可以用作非类型模板参数,但它们必须表示为&Class::member。这似乎通过以下代码得到证实(已检查 在Clang和GCC上):

#include <type_traits>
struct Foo { int bar; };
using X = std::integral_constant<int Foo::*, &Foo::bar>; // works
using Y = std::integral_constant<int Foo::*, X::value>; // fails

因此,我想知道我是否遗漏了标准中的某些内容,或者cppreference.com在这一点上是错误的。如果cppreference.com是正确的,是否有任何理由允许&Foo::bar但不允许X::value

我正在使用C++14 working draft

2 个答案:

答案 0 :(得分:1)

  

我想知道阻止指向数据成员的指针被用作非类型模板参数的基本原理[...]

我不相信它说的。

  

[注意:地址数组元素或非静态数据成员不是可接受的模板参数。 [snip] - 结束说明]

现在,也许我正在阅读本文的措辞, 但我看到 的地址(即&s.s -> int*)和指向成员的指针(即&S::s -> int S::* -> int*)之间存在区别, 允许。

如果您展开[snip],您会看到该笔记已经回答了部分问题:

X<&s.s> x5;  // error: &S::s must be used
X<&S::s> x6; // OK: address of static member

所以cppreference没错。

答案 1 :(得分:1)

在我看来,当前的gcc接受了它,而clang也接受了,因为http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4198.html已经被两者实现了。当然,如果你使用他们的C ++ 17模式。