20

Suppose we want to declare const member function via typedef:

typedef int FC() const;
typedef int F();

struct A
{
   FC fc;         // fine, we have 'int fc() const'
   const F f;    // not fine, 'const' is ignored, so we have 'int f()'
};

Since const is ignored the program compiles fine. Why const is ignored for function? Since we can form const pointer in this way the only thing I can think of is 'C heritage'. Does standard say anything about it?

cigien
  • 57,834
  • 11
  • 73
  • 112
igntec
  • 1,006
  • 10
  • 24
  • `int () const` is mostly a half type, as it may apply only to class to have member functions. – Jarod42 Aug 08 '16 at 10:20
  • It cannot be "C heritage" as C doesn't have member functions. – Jarod42 Aug 08 '16 at 10:21
  • Yes, but in C we still can have: typedef int F(); const F f; even though 'int f() const' may be syntactically incorrect. – igntec Aug 08 '16 at 10:25
  • 1
    Interesting question. Why is it downvoted? It seems that the `const` before `F` is completely ignored. I checked by printing its type and was expecting that it might be `const int (A::*)()` at least. But No, it's simply `int (A::*)()` only. – iammilind Aug 08 '16 at 10:25
  • The only explanation is that const applied to function in C++ is not 'full-right' type. – igntec Aug 08 '16 at 10:26
  • And `const` is ignored not only before `F`, but also after, in a declaration like `F const fc` – alexeykuzmin0 Aug 08 '16 at 10:28
  • 1
    Yes, since order of 'const' and 'F' is not essential. – igntec Aug 08 '16 at 10:31
  • This is a "why is the language the way it is?" question, which we generally cannot answer; only the people actively involved in designing the language can answer, and they might not remember (since this has been this way for a very long time). The committee publishes a "Rationale" document that explains _some_ of the more confusing design decisions, but I suspect it doesn't cover this one. – zwol Aug 08 '16 at 15:01

2 Answers2

19

C++ 14 standard, [dcl.fct] pt. 7:

The effect of a cv-qualifier-seq in a function declarator is not the same as adding cv-qualification on top of the function type. In the latter case, the cv-qualifiers are ignored. [ Note: a function type that has a cv-qualifier-seq is not a cv-qualified type; there are no cv-qualified function types. — end note ]

Example:

typedef void F();

struct S {
    const F f; // OK: equivalent to: void f();
};

So, this is a correct behavior.

alexeykuzmin0
  • 6,344
  • 2
  • 28
  • 51
4

This change is made by CWG 295, essentially to ease generic programming. Consider:

template<class F>
void meow(const F& f) { f(); }
void purr();

meow(purr);

Ignoring the extra const allows this to work.

T.C.
  • 133,968
  • 17
  • 288
  • 421