【问题标题】:Are template arguments required everywhere when mentioning a template base class?提到模板基类时,是否到处都需要模板参数?
【发布时间】:2011-12-19 14:55:53
【问题描述】:

这是一个简单的模板;

template <class T>
class tt {
    private:
        T  x;
    public:
        tt() {x=0;};
        Add(T p) {x += p;};
};

...然后是它的子类;

class cc : public tt<int> {

    public:
        cc() : tt() {};

};

这在 VC 中编译得很好,但在 C++ Builder (XE) 中却没有,它会给出 E2102 错误。 C++ Builder编译器在cc类的构造函数上需要如下语法才能编译;

cc() : tt<int>() {};

实际上,C++ Builder 编译器需要在 cc 类中每次提到 tt 模板时重复模板参数。

标准 C++ 规范是否指定需要不断重复模板参数,还是 C++ Builder 编译器错误?

【问题讨论】:

  • tt 是一个模板。 tt&lt;int&gt; 是一种类型。您只能从类型派生。
  • 你可以使用 typedef 来避免重复
  • @KerrekSB,tt 不是指来自tt&lt;int&gt; 的注入类名吗?
  • 是的,如果我必须重复模板参数,那么 typedef 就是计划。对我来说,定义需要重复似乎有点奇怪,“class cc : public tt”中给出的类型应该足够了,因为我以后不能使用其他参数。
  • @avakar:我认为这仅适用于类模板本身;即如果您说template &lt;typename T&gt; class Foo;,那么Foo 指的是当前实例。不过,我不是 100% 确定。让我们等待一个权威的答案:-)

标签: c++ visual-studio-2010 templates subclassing c++builder-xe


【解决方案1】:

C++ Builder 在这里是错误的。您应该能够在构造函数的成员初始化器列表中使用祖先的名称的原因与注入的类名的概念有关。

当您定义一个类时,编译器会将类的名称插入到该类中并使其引用自身。这个注入的名称允许您在类中使用没有模板参数的类的名称。

template <class T>
struct tt {
    // The compiler behaves as if there was the following.
    // typedef tt<T> tt;
};

当您在成员初始值设定项列表中使用名称 tt 时,会查找此注入名称。

(作为记录,clang 接受不带模板参数的 sn-p。)

奖励:如果您将 cc 定义为具有模板参数 T 的类模板,并且祖先依赖于 T,则名称 tt 将不会在cc 的构造函数的成员初始化列表的上下文。

template <class T>
class cc : tt<T> {
    cc()
        : tt<T>() /* You must use <T> here. */
    {
    }
};

【讨论】:

  • +1 以获得正确的详细答案。另一个有趣的结果:stackoverflow.com/q/5315134/34509
  • 所以g++不对子类注入名字是错的? g++ 4.2 和 4.4 肯定不会选择注入的名称。是否有引用注入的名称是继承的?
  • @MarkB,从技术上讲,来自基类的名称不会注入到子类中;相反,如果在子类中找不到该名称,则查找算法旨在搜索基类中的名称。 g++ 在查找过程中没有找到注入的孩子的名字是错误的。
  • 好的,很高兴知道。笔记;即使 cc 被定义为模板(如在您的示例中但在构造函数中没有 ),VC 也会编译,因此 CBuilder、VC 和 gcc 都无法(以不同的方式)“正确地”执行此操作...跨度>
  • @FrankE,是的,VC 以在实例化点而不是在模板定义点执行某些查找而闻名。一旦cc&lt;T&gt; 被实例化为cc&lt;int&gt;,基类就变成tt&lt;int&gt; 并且tt 的查找成功。
【解决方案2】:

你可以使用 typedef 来避免重复:

typedef tt<int> tti;

...

class cc : public tti {

    public:
        cc() : tti() {};

};

【讨论】:

  • 这只是一种解决方法。不过,它并没有真正回答标准规定的问题。
  • 我知道(如果必须,这就是我的计划)。但是为什么 tt 参数需要重复呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多