Если мой класс 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;
}
Если встроенный оператор предписывает конкретную последовательность, аргументы оцениваются в том же порядке и для перегрузки. Вот соответствующий абзац (из n4659, проект C ++ 17), выделение мое:
[Over.match.oper]
2 Если любой из операндов имеет тип, который является классом или перечислением,
может быть объявлена пользовательская операторная функция, которая реализует
этот оператор или пользовательское преобразование могут быть необходимы для преобразования
операнд типа, который подходит для встроенного оператора. В
В этом случае разрешение перегрузки используется для определения, какой оператор
функция или встроенный оператор должен быть вызван для реализации
оператор. Следовательно, запись оператора сначала преобразуется в
эквивалентная запись вызова функции, как показано в таблице 12 (где @
обозначает один из операторов, охватываемых указанным подпунктом).
Однако операнды упорядочены в порядке, установленном для
встроенный оператор (Пункт [expr]).
Так нет, перегружен operator|
не будет иметь четко определенный порядок оценки, потому что встроенный не имеет.
Других решений пока нет …