在使用 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/