代码之家  ›  专栏  ›  技术社区  ›  YSC

干扰评价顺序

  •  7
  • YSC  · 技术社区  · 8 年前

    Erase–remove idiom :

    v.erase( std::remove_if(v.begin(), v.end(), is_odd), v.end() );
    

    根据我对评估顺序的了解, v.end() (在rhs上)可能会被评估 之前 std::remove_if . 这不是问题,因为 std::remove* 只洗牌向量而不更改其结束迭代器。

    但它可能会导致非常令人惊讶的构造,例如( demo ):

    #include <iostream>
    
    struct Data
    {
        int v;
        int value() const { return v; }
    };
    
    auto inc(Data& data)           { return ++data.v; }
    void print_rhs(int, int value) { std::cout << value << '\n'; }
    
    int main()
    {
        Data data{0};
        print_rhs(inc(data), data.value()); // might print 0
    }
    

    这是令人惊讶的,因为 print_rhs 被称为 之后 inc 被称为;意思是 data.v 1 印刷品 被称为。尽管如此,因为 data.value() 之前 , 0

    我认为,如果计算顺序不那么令人惊讶的话,这可能是一个很好的改进;特别是如果一个有副作用的函数的参数在没有副作用的函数的参数之前被计算出来的话。

    我的问题是:

    • 在C++委员会中讨论过或建议过这种改变吗?
    • 你看到它会带来什么问题吗?
    1 回复  |  直到 8 年前
        1
  •  8
  •   John Zwinck    8 年前

    在C++委员会中讨论过或建议过这种改变吗?

    可能。

    对。它可以减少目前存在的优化机会,除了能够编写更多的单行程序之外,不会带来任何直接好处。但是一句话也不是好事,所以这个提议可能永远不会通过 -99 points