du369 du369 - 1 month ago 7
C++ Question

Does const keyword go before or after Type?

I wrote something like this:

#define Parent C*
class C{
public:
Parent parent;
C():parent(NULL){}
};
void fun(Parent &p){
//condition..return;
fun(p->parent);
}


Something wired happened when I was trying to make the reference parameter constant to avoid any unintended changes to the referenced object.

first:

I added
const
befor
Parent
, like this:
void fun(const Parent &p)
. But it does not compile on this line
fun(p->parent);
.
error message is:


Invalid arguments ' Candidates are: void fun(const C * &) '


then:

I changed the position of
const
like this:
void fun(Parent const &p)
and all of a sudden, the problem was gone.
Why??? What's the difference?

Answer

How does const work? It is always applied to what comes right before it. However, when there is nothing before, it applies to what comes right after it. In other words, const Type& is the same as Type const&.

Now, do not ever use preprocessor macros to define type aliases. There are two ways of doing that in C++: using and typedef. The fact you used a macro is the reason why you observe this peculiar behaviour. The code that fails to compile is expanded to the following:

void fun(const C*& p); // The pointee is const, but the pointer itself is not

I suppose you are then doing things on the object pointed by p... But this object is const! In the second example, the expansion results in:

void fun(C* const& p); // The pointee is not const, but the pointer itself is

Then, you are doing stuff on the pointee but this time it's the pointer, not the pointee, that is const, so everything is fine. If you had used an alias or a typedef, it would have gone perfectly fine in both cases: see this example.

As a rule of thumb, you should always put const on the right of the thing you want it to be applied to. This would allow you to read types the way they are meant to be read: from right to left.

Comments