1

如果我的 C++ 类重载了按位或运算符 ( |),C++ 语言规范是否保证传递给对该运算符的一系列调用的参数将从左到右进行评估?或者评估顺序是定义的(或未定义的)?

(IIRC C++ 的内置|运算符具有实现定义的求值顺序;但是当运算符为类重载时可能会有所不同?)

下面是一个举例说明我要问的程序:这个程序是否保证打印出来0 1 2 3 4(就像它在我目前坐在的 Mac 上所做的那样),或者它是否可以4 3 2 1 0在某些环境中合法地打印出来(或其他一些顺序)?

#include <iostream>

class mytype_t
{
public:
   mytype_t(int v) : _val(v) {/* empty */}

   mytype_t operator | (const mytype_t & rhs) const {return (_val | rhs._val);}

private:
   int _val;
};

mytype_t func(int v)
{
   std::cout << v << std::endl;
   return mytype_t(v);
}

int main(int, char **)
{
   mytype_t x = func(0) | func(1) | func(2) | func(3) | func(4);
   return 0;
}
4

1 回答 1

4

如果内置运算符规定了特定的顺序,则参数也以相同的顺序评估重载。这是相关段落(来自 n4659,C++17 草案),强调我的:

[over.match.oper]

2如果任一操作数的类型是类或枚举,则可能需要声明一个用户定义的操作符函数来实现该操作符,或者可能需要用户定义的转换来将操作数转换为适合构建的类型-in 运算符。在这种情况下,重载决策用于确定要调用哪个运算符函数或内置运算符来实现运算符。因此,运算符符号首先转换为表 12 中总结的等效函数调用符号(其中 @ 表示指定子条款中涵盖的运算符之一)。 但是,操作数按照为内置运算符(子句 [expr])规定的顺序进行排序。

所以不,重载operator|将没有明确定义的评估顺序,因为内置没有。

于 2018-11-28T07:39:21.990 回答