繁体   English   中英

为什么std :: string连接运算符的工作方式类似于右关联运算符?

[英]Why std::string concatenation operator works like right-associative one?

运行从我的宠物项目中提取的以下MWE并使用GCC 4.9.1(以及4.8.1)编译

#include <iostream>
#include <string>
#include <sstream>

class InputStringStream
{
public:
    InputStringStream(const std::string& str) : istringstream(str), currentLine() {}
    std::string readLine()
    {
        std::getline(istringstream, currentLine);
        return currentLine;
    }

private:
    std::istringstream istringstream;
    std::string currentLine;
};

int main()
{
    std::string s = std::string("line1\nline2\nline3");
    InputStringStream stream(s);
    std::cout << stream.readLine() + "\n" + stream.readLine() + "\n" + stream.readLine() << std::endl;
    return 0;
}

产生以下输出

line3
line2
line1

虽然我期待

line1
line2
line3

我做错了什么?

PS使用Apple LLVM编译器版本5.1编译的相同代码产生了我的期望。 Visual C ++ 2012在GCC方面。

函数参数的评估顺序是未指定的 ,所以你做错了就是持有错误的,毫无根据的信念和期望。 (像+<<这样的重载运算符只是普通的函数调用。)

您必须以确定的顺序提取流元素,这是您的责任。 例如:

std::cout << stream.readLine() + '\n';
std::cout << stream.readLine() + '\n';
std::cout << stream.readLine() + '\n';

更好的是,避免冗余和临时字符串:

for (auto i : { 1, 2, 3 }) { std::cout << stream.readLine() << '\n'; }

问题不在于关联性,在这个表达式中:

stream.readLine() + "\n" + stream.readLine() + "\n" + stream.readLine() 

未指定首先调用哪个stream.readLine()

你唯一错误的做法是假设在一个你调用stream.readLine()三次的表达式中,这些表达式的出现顺序与调用顺序相匹配。 有些编译器可能会先评估最后一个调用,有些可能会按顺序对它们进行评估。 理论上,有些人甚至可能首先评估中间人。 这只是C ++的一般规则:表达式的评估顺序未指定。

在所有实现上获得相同结果的简单方法是将三个结果存储在单独的变量中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM