为什么模板参数失去恒定性?

Why is the template parameter losing constness?

本文关键字:恒定性 失去 参数 为什么      更新时间:2023-10-16

我认为这是一个非常基本的问题,但我找不到类似的东西。

以下代码无法编译 (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
{
/*...*/
}
};

它将在从中删除常量后编译

void doStuff (const Param &)

我在这里错过了什么?我希望通过我的接口声明强制执行const Param& in Foo::doStuff。相反,它似乎被删除了。

const

不仅仅是文本替换,它适用于整个类型T

如果TParam&const Tconst Param&不等价;前者与Param& const相同,等价于Param&
如果你写一个不太常见的"postfix-const"形式,它会变得更加明显:无论T是什么,T constParam const &都不能等价。

因此,您的"覆盖"不会覆盖任何内容,并且您会收到编译错误。

当你有

doStuff (const T)

它与

doStuff (const Param &)

第一个是 T 的常量,所以在这种情况下,你有一个对 T 的常量引用,这真的没有意义,因为引用不能反弹。在后面,它是对const Param的引用。

你能做的就是改变

struct Bar : public Foo<Param&>

struct Bar : public Foo<Param>

然后

virtual void doStuff (const T) const = 0;

virtual void doStuff (const T&) const = 0;

问题不在于 const .问题出在覆盖上。 使用 override 声明的成员函数不会重写基类成员