Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the template parameter losing constness?

I thought this is a very basic question but I could not find something similar.

The following code does not compile (C3668)

struct Param
{
    int a;
    int b;
};

template <typename T>
struct Foo
{
    virtual void doStuff (const T) const = 0;
};

struct Bar : public Foo<Param&>
{
    void doStuff (const Param &) const override
    {
        /*...*/
    }
};

It will compile after removing the const from

void doStuff (const Param &)

What am I missing here? I would expect to enforce to the const Param& in Foo::doStuff with my interface declaration. Instead it seems to be removed.

like image 917
Lars Kleen Avatar asked Feb 21 '17 13:02

Lars Kleen


1 Answers

The const isn't just a text substitution, it applies to the entire type T.

If T is Param&, const T and const Param& are not equivalent; the former is the same as Param& const, which is equivalent to Param&.
It becomes more obvious if you write the less common "postfix-const" form: T const and Param const & can't be equivalent regardless of what T is.

Thus, your "override" doesn't override anything and you get a compilation error.

like image 161
molbdnilo Avatar answered Sep 27 '22 21:09

molbdnilo