Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ syntax understanding issue for 'using'

Tags:

c++

I read technical documentation for some projects which are created with C++. I found a line of code that contains syntax I don't understand:

using c = char (& (cClass::* [1]) (cClass(*)[2]) &)[3]; 

I see the using keyword here. That means we deal with an alias, but what does this line do? How can I understand it? I think this creates a named alias c and assigns the result of the expression on the right to it. But what is in this expression?

like image 412
WideWood Avatar asked Mar 13 '21 19:03

WideWood


People also ask

What are syntax errors in C?

Syntax errors: Errors that occur when you violate the rules of writing C/C++ syntax are known as syntax errors. This compiler error indicates something that must be fixed before the code can be compiled. All these errors are detected by compiler and thus are known as compile-time errors.

What is the use of syntax in C programming?

The syntax of the C programming language is the set of rules governing writing of software in the C language. It is designed to allow for programs that are extremely terse, have a close relationship with the resulting object code, and yet provide relatively high-level data abstraction.

What is a syntax error in C examples?

The most commonly occurring syntax errors in C language are: Missing semi-colon (;) Missing parenthesis ({}) Assigning value to a variable without declaring it.


2 Answers

Here's how your type is read, step by step. For the sake of clarity, below we declare a variable x.

T x[1] 

x is an array (length 1) of type T

cClass::* x[1] 

x is an array (length 1) of pointer-to-member inside cClass.

V (cClass::* x[1]) (U) 

x is an array (length 1) of pointer-to-member-function inside cClass. Said member function takes U as argument and returns V.

V (cClass::* x[1]) (U) & 

x is an array (length 1) of pointer-to-member-function inside cClass. Said member function takes U as argument and returns V, and can only be called on lvalues.

V & (cClass::* x[1]) (U) & 

x is an array (length 1) of pointer-to-member-function inside cClass. Said member function takes U as argument and returns reference-to-V, and can only be called on lvalues.

V (& (cClass::* x[1]) (U) &)[3] 

x is an array (length 1) of pointer-to-member-function inside cClass. Said member function takes U as argument and returns a reference to array (length 3) of V, and can only be called on lvalues.

Finally, to get your actual type

char (& (cClass::* x[1]) (cClass(*)[2]) &)[3] 

we choose V = char, and U = (cClass(*)[2]), the latter being a pointer to array (length 2) of cClass.

More readable alternative:

using char3 = char [3]; using ptrTo2cClass = cClass(*)[2]; using ptrToMethod = char3 & (cClass::*) (ptrTo2cClass) &; using c = ptrToMethod[1]; 
like image 129
chi Avatar answered Sep 25 '22 17:09

chi


Types have to be interpreted starting from the middle (where a variable name would be, if it was a variable declaration). You go the right, until you hit the end or ). Then you go to the left, until you hit the beginning or (. At this point you either interpreted the whole type (then you're done), or you're inside of (...), in which case you discard them and repeat the same procedure (go to the right, then to the left).

Since this is not a variable declaration, you first need to find where the variable name would be if it was one. It's easier to do intuitively (once you get some experience), but a decent rule of thumb is to go from the left until you hit either ), or (...), or [...].

Knowing this, we can turn this into a variable declaration. I've added x as the variable name:

char (& (cClass::*x[1]) (cClass(*)[2]) &)[3]; 

Now we can start reading the type. First we go to the right:
x Variable x is...
x[1] an array with 1 element, containing...
(Nothing else to the right, go to the left.)
cClass::*x[1] a pointer to member of class cClass, of type...
(cClass::*x[1]) (Nothing else to the left, skip parentheses.)
(cClass::*x[1]) (............) & a function with some parameters, &-qualified1, returning...
(Nothing else to the right, go to the left.)
& (cClass::*x[1]) (............) & a reference to...
(& (cClass::*x[1]) (............) &) (Nothing else to the left, skip parentheses.)
(& (cClass::*x[1]) (............) &)[3] an array with 3 elements, containing...
char (& (cClass::*x[1]) (............) &)[3] chars

And we're finished. The type of the function parameter (cClass(*)[2]) has to be interpreted separately, using the same procedure. It's "a pointer to an array of size 2, containing cClasses".


1 That & to the right of function parameters means it can only be called on lvalues (the function is "&-qualified").

like image 44
HolyBlackCat Avatar answered Sep 22 '22 17:09

HolyBlackCat