The operator >> (,) overload behaves surprisingly

Well, maybe this is not so surprising. Stackoverflow has a lot of questions and contributions at this point. Only they are not EXACT to the point.

Here's an excerpt from the C ++ standard (actually a C ++ 14 project, but I assume passing in the current C ++ 11 standard):

An operator function must be either a non-static member function or a non-member function that has at least one parameter, the type of which is a class, a class reference, an enumeration, or an enumeration reference. It is not possible to change the priority, grouping, or number of operands of statements. The meaning of the operators =, (unary) & and (comma), predefined for each type, can be changed for certain classes and enumeration types by defining operator functions that implement these operators. operator functions are inherited in the same way as other functions of the base class.

Thus, in my opinion, it is completely legal to have type 1 of type and one non-class type as parameters for the operator → (,). The standard does not say “First” or “Second” parameter. Just the “one” of them should be a class type.

Here is a piece of code that surprises me:

int operator>> ( int v, std::function<int(int)> transformer ) { int v1 = transformer(v); DGS::CLogger::GetLogger()->Log<int>(&IntFormatter, v1 ); return v1; } static int DoItLoggedAndCompact( int value ) { int x = operator>>( operator>>(value, DoIt) , AnotherIntCalculation ); // compiles and works! return x; // The following line produces (with clang++): // error: invalid operands to binary expression ('int' and 'int (*)(int)') // return value >> DoIt >> AnotherIntCalculation; : } 

Note that “function pointer is not a class type”, being a valid instruction, is not an exhaustive answer. As you see in the rewritten code starting with int x = ... and defining the second operator → operator, the function pointer is silently converted to std :: function.

I cannot find anywhere in the standard passage that says that the conversion rules for these two (presumably) synonymous forms are different.

So, is this a compiler error, a wide interpretation of the C ++ specification, or ... something else we see here? Or just some stupid control on my part?

+5
source share
1 answer

But "Function pointer is not a class type" is the correct answer.

In section 13.6, the following note:

operator overload resolution only occurs when the operand expression initially has an enumeration class or type

The normative rule is given in 13.3.1.2 (main attention):

If no operand of the operator in the expression has a type that is a class or an enumeration, the operator is considered a built-in operator and is interpreted in accordance with paragraph 5.

If either operand is of a type that is a class or an enumeration , a user-defined operator function that implements this operator may be declared, or a user-defined conversion may be required to convert the operand to a type that is suitable for the built-in operator. In this case, overload resolution is used to determine which operator function or built-in operator should be called to implement the operator. Therefore, operator notation is first converted to the equivalent function notation , as shown in table 11.

Forms are synonymous only when one of the operands is a class type. Since none of them are here, rewriting as operator>>() does not occur.

+6
source

Source: https://habr.com/ru/post/1210594/


All Articles