【问题标题】:Const keyword in template argument模板参数中的 const 关键字
【发布时间】:2014-06-30 21:52:17
【问题描述】:

我有以下 C++ 代码:

template<typename T> class AbsClass{
public:
    virtual void func(const T elem) = 0;
};

class SolidClass : public AbsClass<char*>{
public:
    void func(const char* elem) {cout << elem << endl;}
};

int main(){
    SolidClass so;
    so.func("xyz");
}

但是,当我尝试在 main() 中实例化 SolidClass 的实例时,编译器 (g++ 4.8.1) 一直抱怨纯虚函数 AbsClass::func(const T elem) 尚未实现的错误。如果我将 SolidClass 的定义更改为以下内容,它将起作用:

class SolidClass : public AbsClass<const char*>{
    .......
}

我只是感到困惑,因为我在声明 AbsClass::func(const T elem) 时已经有了 const 关键字。有人能帮忙解释一下吗?

【问题讨论】:

  • 注意:如果您的编译器支持 C++11,那么您可以编写 void func(const char *elem) override {... override 标记表示此函数旨在覆盖基类中的虚函数,并且如果没有,编译器将标记一个错误(因为在这种情况下它没有:它实际上是一个重载,尽管您打算覆盖)。

标签: c++ templates constants virtual-functions


【解决方案1】:

指针有两种类型的 const。首先是你是否可以修改它们指向的数据——这个 const 意味着更多的“只读”。第二个 const 是指针本身是否是一个常量值——即你是否可以让它指向别的东西。在这种情况下,您的指针 const char* 可以更改为指向其他内容。

要使指针成为常量(因此它不能指向其他任何东西),您必须在 * 之后放置一个 const。所以要让它编译,你的代码应该是:

void func(const char *const elem)

假设你仍然希望它指向的数据通过这个指针是只读的。您需要将模板参数更改为AbsClass&lt;const char*&gt;

如果参数是值,我通常会避免将其设为 const。没有意义,因为它无论如何都会被复制,所以函数的任何本地更改都无关紧要。

【讨论】:

  • SolidClass 在这个定义下仍然是抽象的。
  • @Pradhan 是真的!
  • @Pradhan @Neil 我的意思是const char*,即不能更改内容而不是指针本身。 SolidClass为什么是抽象的有什么解释吗?
  • @user3791869 因为函数中参数需要匹配。 const char * 不是 const T 要求的常量
  • 顶级 const 不是函数签名的一部分。在(const T elem)const char *const elem 的第二个中,const 是否存在对这个问题没有影响。
【解决方案2】:

请记住const T == T const,这样更容易看出句法替换在这里不会产生相同的结果。在这种情况下,将char * 替换为T 在语法上会引起混淆,因为const T 似乎是const char *T constchar *const。实际上const TT const 都产生char *const

static_assert(std::is_same<std::add_const_t<char *>, char *const>::value, "");

【讨论】:

  • 您可能会澄清,实际上const TT const 都是char * const
【解决方案3】:

const char* 是指向const char 的指针。你的意思是说char * const

【讨论】:

  • 不一定。他的意思可能是const char *const
  • @NeilKirk 我说的是定义纯虚拟func 的定义。
  • @NeilKirk 顶级 const 不是函数签名的一部分
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-23
  • 1970-01-01
  • 2012-11-06
  • 2011-08-25
  • 2021-09-02
  • 1970-01-01
  • 2010-11-01
相关资源
最近更新 更多