Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does C++ allow but ignore the application of const to function types?

I get a real kick out of exploring the unusual corners of C++. Having learned about the real types of functions rather than function pointers from this question, I tried messing around with function typing and came up with this bizarre case:

typedef int Func(int);

int Foo(int x) { return 1; }

int main()
{
    const Func*& f = &Foo;

    return 0;
}

Since &Foo is an rvalue of type Func*, I figured that I should be able to put it in a const reference, but I get this error from g++ 4.6:

funcTypes.cpp: In function ‘int main()’:
funcTypes.cpp:7:23: error: invalid initialization of non-const reference of type ‘int (*&)(int)’ from an rvalue of type ‘int (*)(int)’

But f is const! It has become apparent to me that the application of const to a function (or reference/reference to pointer etc.) is simply ignored; this code compiles just fine:

template <typename A, typename B>
struct SameType;

template <typename A>
struct SameType<A, A> { };

typedef int Func(int);

int main()
{
    SameType<const Func, Func>();

    return 0;
}

I'm guessing this is how boost pulls off their is_function type trait, but my question is - why does C++ allow this by ignoring it instead of forbidding it?

EDIT: I realise now that in the first example f is non-const and that const FuncPtr& f = &Foo does work. However, that was just background, the real question is the one above.

like image 386
voltrevo Avatar asked Dec 07 '11 09:12

voltrevo


People also ask

What effect does the const qualifier have when applied to a function argument?

Declaring the parameter 'const' adds semantic information to the parameter. They highlight what the original author of the code had intended and this will aid maintenance of the code as time goes by.

Why might it be good for a function parameter to be const?

Declaring function parameters const indicates that the function promises not to change these values. In C, function arguments are passed by value rather than by reference. Although a function may change the values passed in, these changed values are discarded once the function returns.

Under what circumstances should you declare a function as const?

A function becomes const when the const keyword is used in the function's declaration. The idea of const functions is not to allow them to modify the object on which they are called. It is recommended the practice to make as many functions const as possible so that accidental changes to objects are avoided.

Should you always use const in C?

Always use const for constants that might otherwise be defined using a #define or an enum. The compiler can locate the data in read-only memory (ROM) as a result (although the linker is often a better tool for this purpose in embedded systems).


1 Answers

But f is const!

No, it's not. You're confusing

const Func*& f = &Foo;

with

Func* const& f = &Foo;

The former is a non-const ref to a const pointer. The latter is a const ref to a non-const pointer.

That's why I always write the const-ness before the */& rather than before the type. I would always write the first case as

Func const*& f = &Foo;

and then read right to left: reference to a pointer to a const Func.

like image 188
smparkes Avatar answered Sep 24 '22 04:09

smparkes