【问题标题】:Using a pointer to data member as a non-type template argument使用指向数据成员的指针作为非类型模板参数
【发布时间】:2016-02-14 22:35:49
【问题描述】:

我想知道防止指向数据成员的指针用作非类型模板参数的基本原理,如 [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 是正确的,是否有任何理由允许 &amp;Foo::bar 但不允许 X::value

我正在使用C++14 working draft

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

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

    【讨论】:

    • 当前意思是trunk?因为 5.3.0 在 C++1z 模式下不接受:coliru
    • 是的,现在的意思是trunk。
    • 维尔是正确的; GCC 和 Clang 主干接受我上面发布的代码。
    【解决方案2】:

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

    我不相信它这么说。

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

    现在,也许我正在阅读这篇笔记的措辞, 但我发现地址(即&amp;s.s -&gt; int*)和指向成员的指针(即&amp;S::s -&gt; int S::* -&gt; int*)之间存在区别,允许的。

    如果您扩展 [snip],您会看到该注释已经回答了您的部分问题:

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

    所以cppreference没有错。

    【讨论】:

    • 你展开的例子不是// error: &amp;S::s must be used,而是// error: address of non-static member。但是,我确实同意您的解释很有意义,因此 cppreference 可能是正确的。您是否碰巧知道要求将指向非静态数据成员的指针表示为 &amp;Class::Member 以便可作为非类型模板参数传递的理由?
    • 我刚刚在std-discussion上问了这个问题。
    • @LouisDionne 哦,我引用的是 N4140,你使用的是 N4296
    • 是的,我刚刚意识到这一点。感谢您的帮助,仍然!
    猜你喜欢
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多