c++ - 奇怪的 cout 行为

标签 c++ string

在使用 std::cout 向控制台输出内容时,我注意到一个相当奇怪的行为。
我写了两个函数 string& toUpper(std::string &str)string& toLower(std::string &str) 应该完全按照它们被调用的方式执行:转换字符串全部大写或全部小写。

#include <string>
using namespace std;

string& toLower(string &str)
{
    for(char &c : str)
        c = tolower(c);

    return str;
}

string& toUpper(string &str)
{
    for(auto &c : str)
        c = toupper(c);

    return str;
}

现在我独立测试了这两个功能,它们都按预期工作。然后我将它们链接到一个 cout 调用中:

string str = "Hello World";
cout << toLower(str) << endl << toUpper(str) << endl;

我期望输出是

hello world
HELLO WORLD

但是我刚得到

hello world
hello world

我使用 printf 进行了相同的测试,因为我认为这可能是 cout 做事方式所特有的,但我得到了相同的结果,所以我想我我的代码有问题。
我的代码有什么问题?

最佳答案

调用operator<<必须按从左到右的顺序发生,但 C++ 标准未指定语句中子表达式的求值顺序。

编译器可以决定以何种顺序评估子表达式,以便这些结果中的任何一个都是有效的:

auto&& arg1 = toLower(str);
auto&& arg2 = toUpper(str);
cout << arg1 << endl << arg2 << endl;

或者:

auto&& arg1 = toUpper(str);
auto&& arg2 = toLower(str);
cout << arg2 << endl << arg1 << endl;

或者:

auto&& arg1 = toUpper(str);
auto&& arg2 = (cout << arg1);
auto&& arg3 = toUpper(str);
arg2 << endl << arg3 << endl;

或者其他几种可能性。在这三种可能的排序中,只有最后一种会产生您期望的结果。第一种情况会导致“HELLO WORLD”被打印两次,第二种情况是您使用编译器得到的结果。根据 C++ 标准,所有结果都是有效的。

关于c++ - 奇怪的 cout 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36940675/

相关文章:

string - 可以使一组字符串唯一的最少字符数

javascript - 为什么我不能在不损失 JS 精度的情况下将字符串转换为数字?

c++ - 检测 Windows 10 版本

c++ - 通过 for 循环对 2D vector 进行 Push_back

在 Win 平台中使用 time_t 进行 c++ 时间操作

c++ - 如何使用 NDIS 切换到监控模式?

c++ - 计算文本中单词的频率

c - 在 printf 中通过 %s 在 c 中打印 int

mysql - 无法将字符串格式化为持续时间

c++ - 在64位linux机器上使用32位.a库文件