请解释为什么这个简单的C ++(Qt)代码如此奇怪

时间:2019-07-15 07:35:35

标签: c++ qt

请说明此代码的行为:

#include <QCoreApplication>
#include <QMap>

int testFunc(const QList<int>& data)
{
    // my debugger says data is {0,3}, but I expected {2, 3}. What happened?!
    return data.at(0);
}

int main(int argc, char* argv[])
{
    QCoreApplication a(argc, argv);

    QMap<int, int> test_map;
    int x = test_map.value(1, 2); // // x is 2 (OK)
    test_map[1] = testFunc(
            {
            test_map.value(1, 2), // 2
            3
            });

    return 0;
}

从注释中可以看到,我希望函数传递给包含{2,3}的数组,但是实际上传递了{0,3}(由调试器检查,在Linux上使用gcc 6)。 / p>

1 个答案:

答案 0 :(得分:5)

通常,在C ++中未指定表达式的不同子表达式的求值顺序。在这种情况下,这意味着未指定赋值运算符的哪一侧先被评估。

换句话说,编译器发出先评估test_map[1]然后才评估testFunc调用的代码是完全合法的。当然,如果发生这种情况,那么在评估参数test_map.value(1, 2)时,test_map[1]已经在映射中创建了映射1 : 0,因此test_map.value(1, 2)返回此存在的映射值0,而不使用提供的默认值2

请注意,在这种情况下,以上内容仅适用于C ++ 14和更早版本。从C ++ 17开始,可以确保先评估内置赋值运算符的右侧,然后再从左侧进行评估,因此在C ++ 17中,您看到的行为无效。 / p>