传播“typedef”从“模板”的基类到派生类;
我正在尝试定义仅包含 typedef 的基类。
template<typename T>
class A
{
public:
typedef std::vector<T> Vec_t;
};
template<typename T>
class B : public A<T>
{
private:
Vec_t v; // fails - Vec_t is not recognized
};
为什么在 BI 中收到无法识别 Vec_t 的错误,我需要显式地编写它?
typename A<T>::Vec_t v;
I'm trying to define base class, which contains typedef's only.
template<typename T>
class A
{
public:
typedef std::vector<T> Vec_t;
};
template<typename T>
class B : public A<T>
{
private:
Vec_t v; // fails - Vec_t is not recognized
};
Why in B I receive an error that Vec_t is not recognized and I need to write it explicitly?
typename A<T>::Vec_t v;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我相信这个问题是重复的,但我现在找不到它。 C++ 标准表示您应该根据 14.6.2/3 完全限定名称:
UPD:我终于发现重复的:这是。
I believe that this question is duplicate, but I cannot find it now. C++ Standard says that you should fully qualify name according to 14.6.2/3:
UPD: I found duplicate finally: here it is.
在模板的情况下,有一种称为从属名称和非从属名称的名称。
如果名称依赖于模板参数 T,则其依赖名称,而其他不依赖于参数 T 的名称则为独立名称。
编译器在知道
T
之前无法假定Vec_t
是一种类型,因为A
存在潜在的特化,其中A<< T>:: Vec_t
是一个数据成员所以解决方案是使用 typename
我建议您浏览此 https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-types。
旧(损坏)链接:http://www.parashift.com /c++-faq-lite/templates.html#faq-35.18
There is something called dependent and nondependent names in case of templates.
If name depends on template parameter T its dependent name and others those do not depend on parameter T are independent names.
Compiler cannot assume that
Vec_t
is a type until it knowsT
because There is a potential specialization ofA<T>
whereA<T>:: Vec_t
is a is a data memberSo the solution is use typename
I recommend you go through this https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-types.
Old (broken) link: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18
为了完整起见,您可以通过以下方式稍微减轻这种麻烦:
方法 -
using 声明
将这些名称导入派生类作用域中:如果在派生类中多次提及继承的
typedef
,这会很有用。另外,您不需要每次都添加typename
。For completeness, here's how you could mitigate this nuisance a little, either:
methods -
using declaration
:It can be useful if you have more than one mentioning of the inherited
typedef
in the derived class. Also you don't need to addtypename
each time with this.因为编译器不确定
Vec_t
是否命名了类型。例如,A
可能专门用于T=int
,不具有特定的typedef
。Because the compiler's not certain that
Vec_t
names a type. For example,A<T>
might be specialized forT=int
to not have that particulartypedef
.您需要显式限定
Vec_t
的使用,因为编译器不知道Vec_t
来自何处。它不能假设任何有关 A 结构的信息,因为类模板 A 可能是专门化的。特化可能包含一个不是 typedef 的
Vec_t
,或者它甚至可能根本不包含成员Vec_t
。You need to explicitly qualify the use of
Vec_t
because the compiler does not know whereVec_t
comes from.It cannot assume anything about the structure of A, since the class template A may be specialized. The specialization may include a
Vec_t
which is not a typedef, or it may not even include a memberVec_t
at all.Vec_t 不是依赖名称,编译器需要知道它是什么而不实例化任何模板(在本例中为基类)。它实际上与以下内容没有什么不同:
即使 X 未实例化,编译器也需要了解 std::string,因为名称不依赖于模板参数 T(就编译器可以假设的范围而言)。
总而言之,模板基类中的 typedef 对于在派生类中使用似乎毫无用处。然而,typedef 对用户很有用。
Vec_t is not a dependent name, and the compiler needs to know what it is without instantiating any templates (base class in this case). It is really no different from:
Here as well the compiler needs to know about std::string even if X is not instantiated, since the name does not depend on the template argument T (as far as the compiler can assume).
All in all, typedefs in a template base class seem rather useless for use in derived class. The typedefs are useful for the user, however.
这个概念可以与我们如何使用 std::vector相关联。例如,如果我们有一个
std::vector; Foo
。现在,我们决定使用它的任何成员类型,比如说迭代器。在这种情况下,我们明确提及您的情况类似,以便使用
template的公共成员类型
,您需要将其显式声明为Vec_t
。类 AThis concept can be associated with how we use
std::vector<T>
. For example, if we have astd::vector<int> Foo
. Now, we decide to use any of it's member types, lets say aniterator
. In this scenario we explicitly mentionSimilarly in your case, in order to use a public member type
Vec_t
oftemplate <typename T> class A
, you need to explicitly declare it as