gpt4 book ai didi

c++ - 什么时候实例化模板类的成员函数?

转载 作者:行者123 更新时间:2023-12-01 14:53:56 27 4
gpt4 key购买 nike

考虑以下示例:

template<typename T>
class Base
{
public:
inline void fooBase ()
{
T t; // The following error only occurs when class ABC is not defined at the end of the file: "error: t uses undefined class ABC"
}
protected:
};

class ABC;
class DEF;

class Derived : public Base<ABC>
{
public:
void fooDerived ()
{
DEF def; // error: def uses undefined class DEF
}
};

Derived derived;
void foo ()
{
derived.fooBase ();
}

class ABC {};
class DEF {};

问题
  • 为什么编译器对类 ABC 感到满意只在文件末尾定义?
  • 为什么声明时不需要定义Derived ,也不是在声明全局 foo 时功能?
  • 什么时候实例化模板类的成员函数?即使函数被显式地设置为内联,在 foo () 中调用该函数后,该函数似乎已被实例化(在文件末尾)。 .
  • 这种行为是标准的 C++ 吗?如果是这样,它是否取决于使用的 C++ 版本?

  • 请注意 fooDerived按预期生成错误:在使用该类之前应该(完全)定义该类。

    请注意,没有必要分别回答所有问题,因为它们是同一问题的不同表述。

    测试环境:
  • MSVC(但我对跨平台合规性感兴趣。)
  • 它似乎可以在三个主要编译器(GCC、CLang 和 MSVC)上运行(除了 DEF def; 和预期的一样):https://godbolt.org/z/z_c7mc
  • 最佳答案

    When are member functions of a templated class instantiated?



    声明类模板特化的成员函数与类特化一起实例化,但 定义 仅在需要时实例化。通常在调用成员函数时。只要没有使用成员函数,定义就可能没有被实例化。

    您的示例调用成员函数,因此必须实例化定义。

    然而,特化的成员函数可能有多个实例化点。一个紧接在使用之前,但另一个(总是添加的)在翻译单元的末尾

    [temp.point] (emphasis mine)

    8 A specialization for a function template, a member function template, or of a member function or static data member of a class template may have multiple points of instantiations within a translation unit, and in addition to the points of instantiation described above, for any such specialization that has a point of instantiation within the translation unit, the end of the translation unit is also considered a point of instantiation. A specialization for a class template has at most one point of instantiation within a translation unit. A specialization for any template may have points of instantiation in multiple translation units. If two different points of instantiation give a template specialization different meanings according to the one-definition rule, the program is ill-formed, no diagnostic required.



    这让我进入下一点, fooBase在您显示的翻译单元中有两个实例化点。合一 ABC是不完整的,而在另一个它已经完成。在上面的段落下,您的程序格式错误,不需要诊断。编译器可以对违规保持沉默,同时发出一些似乎有效的代码。但这并不能使程序有效。如果将来更新标准以要求在这种情况下进行诊断,则非法代码将无法构建。如果编译器希望诊断它,它现在甚至可能会失败。

    关于c++ - 什么时候实例化模板类的成员函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59435038/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com