给定以下程序,GCC(g++
,但我假设非std::
位也适用于 C),as can be seen on IDEone.com , 行为如下:
- 它允许在一行中声明多个指针,每个指针都有自己可能不同的
const
限定条件,这是值得尊重的。 - 它不允许多个非指针相同。相反,第一个变量的
const
或缺少它用于该行中声明的所有变量。任何进一步的const
关键字都会产生语法错误。
因此我的问题是:
- 这在指针和非指针情况下都是预期的正确行为吗?
- 为什么在标准化语法方面存在这种差异?
我已经搜索过了,但没有成功。我确实在我面前打开了 n3797.pdf,但我似乎还没有达到理解其语法规范所需的水平。 :( 所以希望有人可以根据需要进行评估和翻译。
请不要只说不要在一行中声明多个变量。我知道为什么不鼓励这样做,但我尽量不这样做。 FWIW,for
循环使它成为获取 const
结束迭代器的一种方式很诱人——如果所述迭代器是一个指针,这似乎是可能的,但如果它是一个类,则不是。无论如何,我不要求代码审查。主题是存在这种差异的原因,与利用它的建议程度无关。
#include <iostream>
#include <type_traits>
int main()
{
int i{42};
int *p1 = &i, *const p2 = &i; // OK
std::cout << std::is_const< decltype(p1) >::value << '\n'; // 0
std::cout << std::is_const< decltype(p2) >::value << '\n'; // 1
int *const p3 = &i, *p4 = &i; // OK
std::cout << std::is_const< decltype(p3) >::value << '\n'; // 1
std::cout << std::is_const< decltype(p4) >::value << '\n'; // 0
int const l = i, m = i; // OK
std::cout << std::is_const< decltype(l) >::value << '\n'; // 1
std::cout << std::is_const< decltype(m) >::value << '\n'; // 1
//int j = i, const k = i; // error: expected unqualified-id before ‘const’
}
最佳答案
正如@JonathanLeffler 指出的那样:
Chapter 8 of n3797.pdf (p180-181) shows that this is OK in the grammar rules there.
声明符列表的每个元素都可以是noptr-declarator 或ptr-declarator。 ptr-declarator 案例的ptr-operator 组件有自己的cv-qualifier-seq opt。但是 noptr-declarator 没有。
法律术语说了这么多,但为什么会这样呢?好吧,一旦我开始更多地考虑这个问题,它就有意义了:前导类型名和声明符列表之间存在明显的区别。非指针声明符创建具有该确切类型的变量,因此具有与其相同的 const
ness。
相比之下,指针声明器也有自己的 const
ness,与引用类型的const 分开。而且我认为声明符列表中的每个指针都可以具有不同的 const
ness 的原因是由于 ptr-operator 绑定(bind)的((in)famous)方式:变量名称,而不是引用的变量类型。
因此,对于像这样的代码,要将其视为“等同于”非指针声明,并意味着“所有这些指针本身都是常量”...
int* const p = &i, q = &j, r = &l;
...那么语法就必须完全不同,并将 ptr-operator 视为类型名的一部分,而不是每个变量的属性。
但正如我们所知,后者才是正确的。因此,考虑到这一点,在每个 ptr-operator 组件中存在一个 cv-qualifier-seq opt 是让甚至一个指针有它自己的 const
ness,与所引用的类型分开。事实上,声明符列表中的每个其他指针都可以具有不同的 const
ness 只是它的一个副作用,因为每个声明符都需要自己的 ptr-operator (以避免成为非指针)。
事后看来,这一切似乎都很明显。我想我今天过得很慢。
关于c++ - GCC 允许 1 行声明多个指针,但不是非指针,具有不同的 const 限定符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44219291/