首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >何时实例化类模板的虚拟方法?

何时实例化类模板的虚拟方法?
EN

Stack Overflow用户
提问于 2013-09-19 15:37:36
回答 2查看 295关注 0票数 2

当生成类模板的虚拟方法的代码时,C++标准是否说明了确切的时间点?

请考虑以下示例:

代码语言:javascript
复制
class Interface
{
  public:
    virtual void f() = 0;
};

template <unsigned int V>
class A : public Interface
{
  public:
    virtual void f()
    {
    }
};

Interface* instantiate()
{
  // class template instantiation with argument V=0
  return new A<0>();
}

// specialization of f() for template argument V=0
template <> void A<0>::f()
{
  cout << "Output from A<0>::f()" << endl;
};

int main() 
{
  Interface* i = instantiate();
  i->f();
  return 0;
}

类模板A声明了一个虚拟方法f()。在我们的示例中,函数实例化()隐式地实例化类模板A,然后执行A<0>::f()的任何显式专门化。在上面的例子中,专门化是在类模板A的隐式实例化之后完成的。现在,至少我的ARM编译器和g++选择了A<0>::f()的专门版本,即主()程序将“输出从A<0>::f()”打印到屏幕上。

我能否始终确保,在类模板隐式实例化之后定义类模板的虚拟方法的专门化就足够了?如果观察到的行为得到C++标准的支持,我会感觉更好。我没有找到任何关于这个问题的明确声明。最接近的部分是14.7.3/6,这在虚拟方法方面有些不明确:

如果模板、成员模板或类模板的成员是明确专门化的,则应在首次使用该专门化之前声明该专门化,这将导致在发生这种使用的每个翻译单元中发生隐式instan- tiation;不需要诊断。如果程序没有为显式专门化提供定义,并且使用专门化的方式会导致隐式实例化发生,或者成员是虚拟成员函数,则程序是格式错误的,不需要诊断。不为声明但未定义的显式专门化生成隐式实例化。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-19 16:43:27

我们很确定是UB。

在实践中:

代码语言:javascript
复制
new A<0>()

将生成对构造函数的调用,而编译器需要该构造函数的定义才可用。如果您试图在此调用之后专门化A<0>::A(),gcc将出错:

代码语言:javascript
复制
error: specialization of ‘A<V>::A() [with V = 0]’ after instantiation

构造函数将具有设置类的多态头的代码,该类将包含指向vtable的指针。在那个vtable中将是Interface::f的条目,但它现在还没有声明最终将填充该槽的符号,您的显式专门化A<0>::f --因此归结为实现的质量问题--编译器是否在完成类类型的同时设计vtable --如果是这样的话,它是否能够在TU中修复该vtable的一个新声明的成员。

票数 2
EN

Stack Overflow用户

发布于 2013-09-19 15:58:42

这方面的标准还很不清楚。有关隐式实例化的相关章节为14.7.1p2:

..。当专门化在要求成员定义存在的上下文中引用时,成员的专门化被隐式实例化;

不幸的是,“要求定义存在”是一个完全没有定义的术语,但我认为,“odr使用的”至少是其中的一个子集,这是一个很好的论点。对于"odr-used",3.2p2中文字的大墙写着:

如果虚拟成员函数不是纯的,则使用odr。

换句话说,虚拟成员仅仅是他们存在的美德(不是双关语)所要求的。

因此,我认为可以提出一个论点,即编译器在实例化包含类时至少可以尝试实例化所有虚拟函数。我不知道有任何编译器会这样做(AFAIK,它们都将实例化延迟到翻译单元的末尾,除非强制不这样做),但我认为您的代码完全不符合要求。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18899102

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档