【问题标题】:The impact of virtual on the use of member of class templatevirtual对类模板成员使用的影响
【发布时间】:2013-11-06 22:48:32
【问题描述】:

我(模糊地)知道如果一个模板没有 使用,它就不会被实例化。例如,即使T::typeT = int 时没有意义,以下代码也能正常编译。

template<typename T>
struct A
{
    void f() { using type = typename T::type; }
};

A<int> a; //ok

它编译是因为f() 没有使用,所以它没有被实例化——因此T::type 的有效性没有被检查。其他一些 member 函数 g() 是否调用 f() 无关紧要。

template<typename T>
struct A
{
    void f() { using type = typename T::type; }

    void g() { f(); } //Is f() still unused?
};

A<int> a; //ok

这也是compile fines。但是在这里我意识到我对“使用”的定义的理解是模糊的。请问:

  • f() 还没有使用吗?具体如何?

我可以清楚地看到它在g() 内部使用。但是后来我想,由于没有使用g(),所以从实例化的角度来看,也没有使用f()。这似乎足够合理。到目前为止。

但是,如果我将 virtual 关键字添加到 g(),它不会编译:

template<typename T>
struct A
{
    void f() { using type = typename T::type; }

    virtual void g() { f(); } //Now f() is used? How exactly?
};

A<int> a; //error

它导致compilation error,因为现在它尝试实例化f()。我不明白这种行为。

谁能解释一下?特别是virtual关键字对类模板成员“使用”定义的影响。

【问题讨论】:

  • 如果我没记错的话,virtual 强制实例化成员函数,因为现在几乎不可能静态评估是否会使用此函数。在实践中,您要求创建一个充满函数指针的 v 表......所以函数需要存在,以便我们可以获取指向它的指针。
  • 结构模板只有在你使用它时才会被实例化。它要么是整个结构,要么什么都没有。它与 g 或 f 没有任何关系。
  • @Sarien:确实如此,模板类的成员函数只有在使用 ODR 时才会被实例化。
  • @Sarien:即使你不使用它们,实例化所有成员也是非常愚蠢的。幸运的是,C++ 很聪明,并且实例化你使用的东西。
  • 真的吗?哇,不知道。

标签: c++ templates c++11 virtual instantiation


【解决方案1】:

快速浏览 3.2 [basic.def.odr] 产生:

3/ [...] 如果虚拟成员函数不是纯的,则它是 odr-used 的。 [...]

我还在 14.7.1 [temp.inst] 找到:

10/ 实现不应隐式实例化不需要实例化的类模板的函数模板、成员模板、非虚拟成员函数、成员类或静态数据成员。 如果虚拟成员函数不会被实例化,则未指定实现是否隐式实例化类模板的虚拟成员函数。(强调我的)

所以...我想说virtual 方法很可能总是会被实例化。

从实用的角度来说,我希望编译器在实例化模板类时实例化模板类的虚拟表;并因此立即实例化该类的所有virtual 成员函数(因此它可以引用虚拟表中的那些)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 2012-11-04
    • 2012-01-22
    • 2021-09-18
    • 1970-01-01
    • 2011-04-18
    相关资源
    最近更新 更多