Why does the template parameter lose its constant?

I thought this was a very simple question, but I could not find something like that.

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 compiles after removing the constant from

 void doStuff (const Param &) 

What am I missing here? I would expect a forced application to const Param& in Foo::doStuff with my interface declaration. Instead, he seems to be retiring.

+6
source share
3 answers

const is not just textual substitution, it applies to the whole type of T

If T is Param& , const T and const Param& not equivalent; the first is the same as Param& const , which is equivalent to Param& .
This becomes more apparent if you write a less common form of "postfix-const": T const and Param const & cannot be equivalent, no matter what T

Thus, your “override” does not cancel anything, and you get a compilation error.

+5
source

If you

 doStuff (const T) 

this is not the same type as

 doStuff (const Param &) 

The first is a constant, regardless of the fact that T in this case has a permanent link to T, which really does not make sense, since the links cannot be restored. In the future, this is a link to const Param .

What you can 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; 
+1
source

The problem is not with a constant. The problem is with redefinition. A member function declared with an override does not override a base class member

+1
source

Source: https://habr.com/ru/post/1015148/


All Articles