为什么在C++ 11中删除了对逗号运算符的限制在常量表达式中删除了?

Sha*_*our 20 c++ language-lawyer constant-expression c++11 c++03

最近在回答问题时,我意识到只要表达式被包围,逗号运算符就被允许在C++ 11中的常量表达式中(),例如:

int a[ (1, 2) ] ;
Run Code Online (Sandbox Code Playgroud)

在C++ 11中,禁止在常量表达式中使用逗号运算符,来自草案预C++ 11标准部分5.19 常量表达式(强调我的):

[...]特别是,除了sizeof表达式,不应使用函数,类对象,指针或引用,并且不得使用赋值,递增,递减,函数调用或逗号运算符.

为什么逗号运算符不允许在C++ 11之前的常量表达式中,为什么解除了这个限制?

Sha*_*our 18

我们可以在常量表达式线程中的std-discussion逗号运算符中找到答案,其中Gabriel Dos Reis说:

对于C++ 11,我建议允许它,因为限制似乎是任意的,而且我所听到的所有理由都是禁令的理由对我来说非常难以理解.

线程中早期的 Richard Smith C++ 11和C++ 14中指出了逗号运算符常量表达式中的一些用法:

我不同意你的论点和结论.在C++ 11中,逗号运算符在constexpr函数中很有用,因为我们不允许多个语句:

template<typename T>   constexpr T my_array<T>::at(size_type n) {
  return (n < size() || throw "n too large"), (*this)[n];   }
Run Code Online (Sandbox Code Playgroud)

在C++ 14中,它在基本上所有在常量表达式之外有用的情况下很有用:

constexpr void do_stuff(int x[]) {
  for (int i = 0, j = 100; i != j; ++i, --j)
    x[i] = x[j];   }
Run Code Online (Sandbox Code Playgroud)

更哲学上,我们不应该仅仅因为我们没有足够的想象力来发现它们真正有用的案例而禁止不断表达.常量表达式不应该是C++的半随机子语言,缺少随机特征,以至于我们可以避免这种情况.目前,禁止使用顶级逗号主要是因为常量表达式往往发生在逗号意味着其他内容的上下文中.

请注意,有人认为他的C++ 11示例不正确,因为包含逗号运算符的表达式应该在,()但他的示例给出了参数的本质.该参数将基于5.19 Constant表达式中的语法:

constant-expression:
   conditional-expression
Run Code Online (Sandbox Code Playgroud)

我们无法从条件表达式获取逗号运算符,但是我们可以使用primary-expression来获取,然后我们可以从表达式获取逗号运算符.( expression )

TC 指出,情况可能并非如此,因为相关部分在这一点上似乎含糊不清.