7

Consider the following example:

#include <iostream>
#include <string>

class Base {
public:
    virtual void func(int a) {}
};

class Derived : public Base {
    public:
    void func( const int a) override {
    }
};


int main()
{
    Derived d;
    d.func(1);

    return 1;
}

I override the func method but add const to the parameter, in which case the linker should scream that something is wrong. Either the function is not overridden or the function parameter should not be const.

But to my surprise, this code links and works.

You can find an online example here.

Am I missing something? Why does this code work?

Although similar to Functions with const arguments and Overloading it addresses a different problem. That question was about not being possible to overload a method of the base class, while this question addresses the problem of being able to override a derived method.

Boann
  • 48,794
  • 16
  • 117
  • 146
Izzy
  • 402
  • 6
  • 16
  • @dewaffled no its not. Overloading and overriding are two different things – Izzy Jun 19 '19 at 07:43
  • @lzzy Yes, but the [the answer there](https://stackoverflow.com/a/3682076/4074081) answers your question as well and looked clear enough to repost here: §13.1 where the Standard.. Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored – dewaffled Jun 19 '19 at 07:46
  • @dewaffled Yes you are right, the answer does answer my question, but my question *is* different. – Izzy Jun 19 '19 at 07:50

1 Answers1

9

Because their signatures are the same in fact.

The type of each function parameter in the parameter list is determined according to the following rules:

...

4) Top-level cv-qualifiers are dropped from the parameter type (This adjustment only affects the function type, but doesn't modify the property of the parameter: int f(const int p, decltype(p)*); and int f(int, const int*); declare the same function)

That means, void func(int a) and void func(const int a) are considered as the same function type; then the overriding is valid.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • Thanks. Just one fast question: does overridden method with const use const signature? Or is dropped as I see in your comment? – Izzy Jun 19 '19 at 07:47
  • 3
    @Izzy As the quote says, *but doesn't modify the property of the parameter*, so the parameter is still `const` in the function, i.e. you can't modify the parameter `a` inside the body of `Derived::func`. [LIVE](https://wandbox.org/permlink/opOprhy9NmjP1PTP) – songyuanyao Jun 19 '19 at 07:49