简体   繁体   English

三元运算符的异常行为

[英]Unexpected behavior from ternary operator

When I run this code: 当我运行此代码时:

#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;
}

I get the following output: 我得到以下输出:

2
1

Why am I getting wrong output when I am using ternary operator? 为什么使用三元运算符时输出错误?

The order of function calls is indeterminate and affecting your results. 函数调用的顺序不确定并且会影响您的结果。 Consider: 考虑:

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;
}

This is a perfectly legal implementation of the code you wrote. 这是您编写的代码的完全合法的实现。

There's nothing wrong with the ternary operator. 三元运算符没有错。 This would work just fine: 这样就可以了:

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

The important thing is whether m[5] could possibly be evaluated before m.find(5) . 重要的是,是否可以在m.find(5)之前对m[5]进行评估。

In this statement 在此声明中

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

you created object m[5] by placing it in the left side of the assignment. 您通过将对象m [5]放在任务的左侧来创建了该对象。 So m.find(5) != m.end() because m[5] already exists. 所以m.find(5)!= m.end()因为m [5]已经存在。

In fact there is the undefined behaviour because the order of evaluation of the left and the right operands of the assignment is not specified. 实际上,存在未定义的行为,因为未指定赋值的左操作数和右操作数的评估顺序。

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

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