C ++ 17: What does “operator with priority below cast” mean in the concept of “fold”?

See http://en.cppreference.com/w/cpp/language/fold for an example of using the fold concept, which states:

Note If the expression used as init or as pack has an operator with precedence below cast at the top level, it can be parenthesed: template<typename ...Args> int sum(Args&&... args) { // return (args + ... + 1 * 2); // Error: operator with precedence below cast return (args + ... + (1 * 2)); // OK } 

As not speaking English, I do not leave a sentence:

 has an operator with precedence below cast at the top level 

What does this mean, and is it an example of what it points to? Could you explain this?

Thank you very much.

+5
source share
2 answers

The casting operator ( (Typename)expr ) has a very high priority in the priority rules of C ++ operators . Very few operators have a higher priority than this. Fill level operators or higher priority are very special operations that usually apply to a single expression.

In the expression args + ... + 1 * 2 , ... applies to all both left and right. But what does "right" mean? Does this only mean part + 1 , or does it mean + 1 * 2 ?

In the case of operators with high priority, it is clear what this intent is. For example, args + ... + func() , it is clear that the function call operator () applies to func , and not to args + ... + func . This is so unlikely that you want the last one to force you to use parentheses if you did ( (args + ... + func)() ).

However, for priority levels below 3, the graph for people is becoming increasingly muddy. Therefore, instead of using the usual priority rules, C ++ forces the user to be explicit. You can have args + ... + (1 * 2) or (args + ... + 1) * 2 . But you must be clear what you want.

+7
source

This means that if an expression with several operators is ambiguous, operators that are “exceeded” will be called before the casting operator, and operators that are “below the cast” will be called after the translation operator. As in 2 + 2 * 2 , multiplication must be performed before addition, the result is 6, but not 8.

Consider the following two classes that can be written off with each other:

 class E2; class E1 { public: operator E2(); E1 operator++(int) { std::cout << "E1 Post-inc\n"; return *this; } E1 operator*(const E1&) { std::cout << "E1 * E1\n"; return *this; } }; class E2 { public: operator E1() { std::cout << "Cast E1 -> E2\n"; return E1(); } E2 operator++(int) { std::cout << "E2 Post-inc\n"; return *this; } E2 operator*(const E2&) { std::cout << "E2 * E2\n"; return *this; } }; E1::operator E2() { std::cout << "Cast E2 -> E1\n"; return E2(); } 

Then let declare

 E1 e1; E2 e2; 

and do

 (E1)e2++; 

Both E1 and E2 have a ++ operator, so what should be done first in this expression: pour or increase? The priority table answers that the increment should be executed first, so the program prints

 E2 Post-inc Cast E1 -> E2 

Then try a more complex example:

 e1 * (E1)e2++; 

Here we have 3 actions (in the order they appear in the code): multiplication, cast and increment. What order if the execution will be? The use case table says that the increment is the first, the cast is the second (it is lower than the increment), and the multiplication is the last, since it is lower than both. Thus, the output will be:

 E2 Post-inc Cast E1 -> E2 E1 * E1 

Note that you can easily reorder operations using parentheses. For example, if we replace e1 * (E1)e2++; on (e1 * (E1)e2)++; , we'll get

 Cast E1 -> E2 E1 * E1 E1 Post-inc 
+1
source

All Articles