Reputation: 63
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.
Upvotes: 6
Views: 173
Reputation: 3632
Problem is not with const .Problem is with the override. Member function declared with override doesn't override a base class member
Upvotes: 1
Reputation: 66371
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.
Upvotes: 5
Reputation: 180630
When you have
doStuff (const T)
it is not the same type as
doStuff (const Param &)
The first one is a constant whatever T is so in this case you have a constant reference to a T which really doesn't make sense since references cannot be rebound. In the later it is a reference to a const Param
.
What you could do is change
struct Bar : public Foo<Param&>
to
struct Bar : public Foo<Param>
and then
virtual void doStuff (const T) const = 0;
to
virtual void doStuff (const T&) const = 0;
Upvotes: 1