c++ - 括号是否会使指针模板参数无效?

标签 c++ templates language-lawyer

考虑这段代码:

int x = 0;

template<int& I>
struct SR {};

template<int* I>
struct SP {};

SR<(x)> sr;
SP<&(x)> sp;

int main(void)
{
}

clang++ 3.8.0 提示:

main.cpp:10:5: error: non-type template argument does not refer to any declaration
SP<&(x)> sp;
    ^~~
main.cpp:6:15: note: template parameter is declared here
template<int* I>
              ^

g++ 6.1.0 提示:

main.cpp:10:8: error: template argument 1 is invalid
 SP<&(x)> sp;
        ^

当然,如果我删除括号,一切正常,如 SP<&x> sp; .但是我在 C++14 标准中找不到任何会在这里有所作为的内容。此外,为什么引用案例没问题但指针案例不好?编译器拒绝该程序是否正确?

最佳答案

我对该标准的理解是它应该被允许,但我想 GCC 和 Clang 的实现者不同意我的解释,他们可能是正确的。要获得明确的答案,询问 std-discussion@isocpp.org 邮件列表可能是个好主意(我会给他们发一封电子邮件)。措辞可能有缺陷。

根据 [temp.arg.nontype],非类型模板参数的一种可能形式是:

... a constant expression (5.19) that designates the address of a complete object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as &id-expression, where the id-expression is the name of an object or function, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference ...

这一切都取决于“忽略括号”的含义。 GCC 和 Clang 都接受 (&x) 但不接受 &(x);他们似乎已经决定“忽略括号”仅意味着在外部,而不是在 id 表达式周围。如果这是标准委员会的意图,则应该澄清语言。

编辑:C++17 draft ,这是明确允许的,因为允许的非类型模板参数的形式已大大放宽:

A template-argument for a non-type template-parameter shall be a converted constant expression ([expr.const]) of the type of the template-parameter. For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):

  • a subobject ([intro.object]),
  • a temporary object ([class.temporary]),
  • a string literal ([lex.string]),
  • the result of a typeid expression ([expr.typeid]), or
  • a predefined __func__ variable ([dcl.fct.def.general]).

关于c++ - 括号是否会使指针模板参数无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39777331/

相关文章:

c++ - 为什么 Visual Studio 无法编译我的 QT 项目,因为它找不到库?

C++ 特化模板类中的单个方法

c++ - 为什么我不能使用 std::Optional<T> (其中 T 是抽象的)?

c++ - 为什么 bool 到 string 的隐式转换不是错误?

c++ - MSVC 无法返回可以复制但不能移动的对象

c++ - 使用 While 语句从控制台读取

c++ - 使用用 c/c++ 编写的共享库的 Linux C 程序

c++ - 为什么我们需要使用 virtual ~A() = default;而不是 C++11 中的虚拟 ~A() {}?

c++ - 检查完整类型

c - 与严格别名相关的有效类型规则