gpt4 book ai didi

c++ - 运算符 << - 参数评估的顺序

转载 作者:行者123 更新时间:2023-11-28 00:55:56 25 4
gpt4 key购买 nike

从这个问题和答案 - What is the correct answer for cout << c++ << c;?

我明白了

std::cout<<c++<<c;

被评估为:

std::operator<<(std::operator<<(std::cout, c++), c);

所以未定义的行为来自于两个参数中的任何一个都可以首先被评估的事实。到目前为止一切顺利。

但是为什么std::operator << ?为什么不是 std::ostream::operator <<叫什么?如果是,它不会转化为

(ofstream::operator<<(c++)) << c;
|
returns ofstream&

这和方法链有什么区别:

struct A
{
A& foo();
void goo();
};
//...
A a;
a.foo().goo();

?

最佳答案

std::ostream提供 operator<<作为重载成员运算符,但其他 header (例如 <string> )提供免费运算符;所以是否<<是成员运算符还是自由函数取决于 RHS 类型。

不过,这两种方式都没有关系。让我们重命名 <<作为foocout作为bar :

foo(foo(bar, c++), c);
bar.foo(c++).foo(c);

在这两种情况下,行为都是未定义的,因为没有要求实现来评估调用 foo 的参数。以任何特定顺序。重要的考虑是,根据附件 C,链式方法调用不构成多个完整表达式;如果编译器看到

foo.bar(<some-complex-expression>).baz(<another-complex-expression>);

可以免费应用 CSE 并重新排序到 bar 的参数和baz ;事实上,对副作用的检查可能表明 baz 的论点在 bar 之前进行评估.

struct A { A &foo(int) { return *this; } };
#include <cstdio>
int main() { A().foo(printf("hello\n")).foo(printf("bye\n")); }

我的编译器 (gcc 4.1.2) 生成一个打印 bye\nhello\n 的程序.

关于c++ - 运算符 << - 参数评估的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11262006/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com