12

我在编码时不小心在常量引用和它的默认值之间留了一个空格。我惊讶地发现它在 Intellisense 中作为错误出现,所以我编译了它,果然,它在 GCC 4.3.4、4.5.1 或 4.7.2 中不起作用,并且在Visual Studio 2012,或者。

这是一个演示错误的等效示例:

struct S {
    S(const int &= 5){}    
};

int main(){}

这会在 GCC 中产生以下错误,在 MSVC 中产生类似错误:

错误:在 '&=' 标记之前应有 ',' 或 '...'

我认为这是因为&=被视为运算符,但我不确切知道在标准中搜索什么以查找有关此案例的更多信息。&= 只是提供特定于操作员的信息。

出于好奇,我决定将其换成右值参考:

S(int &&= 5){}

奇怪的是,这在 GCC 4.7.2 和 MSVC 上都编译得很好,这意味着 &= 并不总是作为运算符在词法上配对。

为什么它适用于右值引用,而不适用于左值引用,标准对此事有什么看法?

4

2 回答 2

14

这通常被称为“最长匹配原则”或“最大咀嚼”。因为&&是一个有效的记号而&&=不是(没有复合赋值符号),所以以 ;开头&&的最长记号是; 删除之后,就没有机会被视为单个令牌。&&=&&&=

这个原则对许多语言来说是共同的,尽管它经常有例外。例如,在 C++11 中,>>将在.>>std::vector<std::vector<int>>

于 2012-11-29T21:03:31.710 回答
6

解析器只是从左到右工作,不管关联性如何,所以在第一个示例中,它找到的第一个完整标记是&=. (此时,解析器还没有检查更大的结构,所以它只知道那里有那个标记。)

在第二个示例中,它找到的令牌是&&。因为&&=不是令牌!

于 2012-11-29T21:01:20.927 回答