I want to evaluate a()|b()
left-to-right, but I get a different order depending on whether I use the built-in operator or a custom operator.
class Foo {
public: Foo operator| (Foo f) {
return Foo();
}
};
std::string out;
auto f1 = [&out](std::string s) { out += s; return false; };
auto f2 = [&out](std::string s) { out += s; return Foo(); };
f1("a") | f1("b");
f2("c") | f2("d");
std::cout << out;
The output is abdc
. How do I make the custom operator evaluate left-to-right?
You cannot. At least not with an overloaded operator|
. The evaluation order of operands to functions and most operators in unspecified in C++.
For the built-in ||
, operator order is left-to-right, but you cannot overload that operator to return anything but bool
because it would cease to be "built-in ||
".
If you give your Foo
class an operator bool() const
which converts to bool
, then you can write f2("x") || f2("y")
but the right expression will not be evaluated if the left evaluates to true, and it will very likely emit a branch instruction in the compiler's output.
You could overload operator,
(or use the built-in) as well, which then would be sequenced in the way you are looking for.
- Every value computation and side effect of the first (left) argument of the built-in logical AND operator &&, the built-in logical OR operator || and the built-in comma operator , is sequenced before every value computation and side effect of the second (right) argument.
- Every value computation and side effect associated with the first expression in the conditional operator ?: is sequenced before every value computation and side effect associated with the second or third expression.