传播“typedef”从“模板”的基类到派生类;

发布于 2024-08-09 21:50:50 字数 365 浏览 6 评论 0原文

我正在尝试定义仅包含 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

同尘 2024-08-16 21:50:50

我相信这个问题是重复的,但我现在找不到它。 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:

In the definition of a class template or a member of a class template, if a base class of the class template depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.

UPD: I found duplicate finally: here it is.

笨笨の傻瓜 2024-08-16 21:50:50

在模板的情况下,有一种称为从属名称和非从属名称的名称。

如果名称依赖于模板参数 T,则其依赖名称,而其他不依赖于参数 T 的名称则为独立名称。

规则如下:编译器不会
查看依赖基类(例如
A)查找非依赖时
名称(如 Vec_t)。因此,
编译器甚至不知道它们
存在更不用说是类型了。

编译器在知道 T 之前无法假定 Vec_t 是一种类型,因为 A 存在潜在的特化,其中 A<< T>:: Vec_t 是一个数据成员

所以解决方案是使用 typename

 typename A<T>::Vec_t v;  ← good

我建议您浏览此 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.

Here's the rule: the compiler does not
look in dependent base classes (like
A) when looking up nondependent
names (like Vec_t). As a result,
the compiler does not know they even
exist let alone are types.

Compiler cannot assume that Vec_t is a type until it knows T because There is a potential specialization of A<T> where A<T>:: Vec_t is a is a data member

So the solution is use typename

 typename A<T>::Vec_t v;  ← good

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

泛滥成性 2024-08-16 21:50:50

为了完整起见,您可以通过以下方式稍微减轻这种麻烦:

  • 在派生类中重新 typedef 这些类型,或者更好 - 就像
    方法 -
  • 只需使用 using 声明 将这些名称导入派生类作用域中:

template<typename T>
class A
{
public:
    typedef std::vector<T> Vec_t;
};


template<typename T>
class B : public A<T>
{
public:
    using typename A<T>::Vec_t;
    // .........

private:
    Vec_t v;
};

如果在派生类中多次提及继承的 typedef,这会很有用。另外,您不需要每次都添加 typename

For completeness, here's how you could mitigate this nuisance a little, either:

  • re-typedef those types in derived classes, or better - as with
    methods -
  • just import those names in the derived class scope with a using declaration:

template<typename T>
class A
{
public:
    typedef std::vector<T> Vec_t;
};


template<typename T>
class B : public A<T>
{
public:
    using typename A<T>::Vec_t;
    // .........

private:
    Vec_t v;
};

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 add typename each time with this.

江挽川 2024-08-16 21:50:50

因为编译器不确定 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 for T=int to not have that particular typedef.

汹涌人海 2024-08-16 21:50:50

您需要显式限定 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 where Vec_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 member Vec_t at all.

情绪操控生活 2024-08-16 21:50:50

Vec_t 不是依赖名称,编译器需要知道它是什么而不实例化任何模板(在本例中为基类)。它实际上与以下内容没有什么不同:

template <class T>
class X
{
    std::string s;
}

即使 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:

template <class T>
class X
{
    std::string s;
}

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.

如果没有 2024-08-16 21:50:50

这个概念可以与我们如何使用 std::vector相关联。例如,如果我们有一个 std::vector; Foo。现在,我们决定使用它的任何成员类型,比如说迭代器。在这种情况下,我们明确提及

std::vector<int>::iterator foo_iterator;

您的情况类似,以便使用 template的公共成员类型 Vec_t 。类 A,您需要将其显式声明为

A<T>::Vec_t v;
OR
A<int>::Vec_t int_type;

This concept can be associated with how we use std::vector<T>. For example, if we have a std::vector<int> Foo. Now, we decide to use any of it's member types, lets say an iterator. In this scenario we explicitly mention

std::vector<int>::iterator foo_iterator;

Similarly in your case, in order to use a public member type Vec_t of template <typename T> class A, you need to explicitly declare it as

A<T>::Vec_t v;
OR
A<int>::Vec_t int_type;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文