来自三元运算符的意外行为

时间:2014-05-13 16:48:22

标签: c++ ternary-operator

当我运行此代码时:

#include <iostream>
#include <map>

using namespace std;

void f1() {
    map<int, int> m;
    m[5] = m.find(5) == m.end() ? 1 : 2;
    cout << m[5] << endl;
}
void f2() {
    map<int, int> m;
    if (m.find(5) == m.end())
        m[5] = 1;
    else
        m[5] = 2;
    cout << m[5] << endl;
}
int main() {
    f1();
    f2();
    return 0;
}

我得到以下输出:

2
1

当我使用三元运算符时,为什么输出错误?

2 个答案:

答案 0 :(得分:2)

函数调用的顺序是不确定的,会影响您的结果。考虑:

void f1()
{
    map<int, int> m;
    int& result = m[5]; // creates m[5]
    auto it = m.find(5); // finds the empty m[5] created above
    int value = (it == m.end())? 1: 2;
    result = value;
    std::cout << m[5] << std::endl;
}

这是您编写的代码的完美合法实现。

三元运算符没有问题。这样可以正常工作:

bool notfound = (m.find(5) == m.end());
m[5] = notfound? 1: 2;

重要的是m[5]之前是否可以评估m.find(5)

答案 1 :(得分:-1)

在本声明中

m[5] = m.find(5) == m.end() ? 1 : 2;

您通过将对象m [5]放在作业的左侧来创建对象。所以m.find(5)!= m.end()因为m [5]已经存在。

实际上存在未定义的行为,因为未指定分配的左侧和右侧操作数的评估顺序。