【问题标题】:Why is the template parameter losing constness?为什么模板参数会失去常量?
【发布时间】:2017-02-21 13:52:44
【问题描述】:

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

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

去掉 const 后会编译

void doStuff (const Param &)

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

【问题讨论】:

  • 顶级常量在函数声明中被忽略。此外,const T 表示 Param&amp; const,而不是 const Param&amp;

标签: c++ templates interface


【解决方案1】:

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

如果TParam&amp;,则const Tconst Param&amp; 不等价;前者等同于Param&amp; const,相当于Param&amp;
如果您编写不太常见的“postfix-const”形式,则变得更加明显:T constParam const &amp; 不能等同,无论 T 是什么。

因此,您的“覆盖”不会覆盖任何内容,并且会出现编译错误。

【讨论】:

    【解决方案2】:

    当你有

    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;
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2021-04-06
        • 2012-02-07
        • 1970-01-01
        • 2011-05-09
        • 1970-01-01
        • 1970-01-01
        • 2019-06-15
        • 1970-01-01
        相关资源
        最近更新 更多