【问题标题】:Type not found when derived from template base class从模板基类派生时找不到类型
【发布时间】:2013-03-06 00:36:26
【问题描述】:

我很难理解为什么以下两段代码会有所不同,编译器到底在做什么。

我有以下一些琐碎的代码,可以按预期编译没有任何问题:

class base
{
public:
   typedef int booboo;
};

class derived : public base
{
public:
   int boo()
   {
      booboo bb = 1;
      return bb;
   }
};

int main()
{
   derived d;
   d.boo();
   return 0;
}

我从上面获取代码并添加一些模板参数,然后开始收到与 booboo 类型无效相关的错误:

template <typename T>
class base
{
public:
   typedef T booboo;
};

template <typename T>
class derived : public base<T>
{
public:
   //typedef typename base<T>::booboo booboo; <-- fixes the problem
   booboo boo()
   {
      booboo bb = T(1);
      return bb;
   }
};

int main()
{
   derived<int> d;
   d.boo();
   return 0;
}

错误:

prog.cpp:13:4: error: ‘booboo’ does not name a type
prog.cpp:13:4: note: (perhaps ‘typename base<T>::booboo’ was intended)
prog.cpp: In function ‘int main()’:
prog.cpp:23:6: error: ‘class derived<int>’ has no member named ‘boo’

http://ideone.com/jGKYIC

.

我想详细了解一下,典型的 c++ 编译器如何编译代码的模板版本,它与编译原始示例有何不同,这是否与代码的多次传递有关,以及类型依赖查找?

【问题讨论】:

  • 将您遇到的错误作为问题的一部分发布总是值得的。
  • @JBentley:抱歉更新一下,我现在就更新问题。

标签: c++ templates inheritance compiler-errors type-deduction


【解决方案1】:

在第二个版本中,booboo 是一个依赖名称,因此它不会自动在模板中可见。您可以将 using typename base&lt;T&gt;::booboo; 添加到派生类中,或者使用您的 typedef 解决方案,或者说 typename base&lt;T&gt;::booboo bb = T(1);

【讨论】:

  • 只是为了澄清,本质上这意味着编译器一开始不能保证没有省略booboo定义的基类模板的特化,或者可能定义@ 987654325@ 作为函数或其他。因此必须告诉编译器对名称的假设:它来自基类,并且它是一种类型。
  • @Kerrek:您是否碰巧知道标准中描述/讨论在处理模板时类型何时可见的部分?或者它是一个实现定义的问题?
  • @SamiKenjat:它是 C++11 中的 14.6.2,“从属名称”。基本上,:: 右侧的任何名称,如果左侧是模板特化。
  • 这包括方法吗?因为我相信有时在从同样模板化的类中调用模板方法时需要使用“模板”一词。
  • @SamiKenjat:对于模板名称,您需要说 template,对于类型名称,您需要说 typename,对于类似值的名称则不需要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-09
  • 2011-11-19
  • 2018-03-30
  • 2021-08-09
  • 2017-01-13
  • 2016-02-23
  • 2010-12-11
相关资源
最近更新 更多