【问题标题】:How do template member functions work in c++?模板成员函数如何在 C++ 中工作?
【发布时间】:2016-07-26 22:11:49
【问题描述】:

我想知道模板成员函数是如何工作的。特别是当有模板成员函数的实例化时,是不是整个类都被重新定义了?我的困惑来自这样一个事实(如果我是对的)模板类不是正确意义上的类。即,当实例化时,编译器为一个全新的类创建定义。模板函数也是如此。但是,具有模板函数的类似乎是实际的类,所以我不确定它们如何工作。因此,我想知道,在实例化模板成员函数之后,类定义会发生什么?此外,如果我将带有模板成员函数的类传递给模板类,我可以使用模板成员函数吗?这会导致问题吗?我尝试了一次,但得到一个错误,说几个函数定义了不止一次,尽管我不确定这是否是原因,或者是否有其他原因导致我的错误。使用静态模板成员函数时还有什么需要注意的吗?

【问题讨论】:

  • 模板的特化,无论是类模板还是函数模板,在第一次在翻译单元中使用时都会被实例化。类可以有成员模板(类和函数模板),类模板也可以。此外,类模板的成员函数本身就是隐含的函数模板。
  • 请注意,模板永远不会被实例化。只能实例化模板的特化。
  • 很好,谢谢。
  • “模板类不是正确意义上的类” 你的困惑来自于称它们为“模板类”。它们是类模板。它们不是类,而是用于制作类的模板。
  • 我的编译器使用精灵魔法。

标签: c++ templates static member


【解决方案1】:

类定义保持原样;模板函数所做的只是为该类生成一系列成员函数。举个例子:

class A {
    public:
        template<typename T> foo (T &t);
}

和你写的概念上没有区别:

class A {
    public:
        foo (bool &t);
        foo (int &t);
        foo (double &t);
}

...只是更方便。在最后一个示例中,您不会期望为每个函数创建一个新类吧?

也许混淆来自于这样一种观念,即函数在某种程度上是类的内存布局的一部分;每个函数本身都包含在类中,并且每当创建类的对象时都会在内存中的某个位置实例化。这种观念是不正确的。函数(模板化、全局、成员、lambda 或其他)永远不会动态创建或在内存中复制;它们是可执行映像的静态且不变的部分。类的内存布局不会因存在一组额外的函数而改变,即使这些函数恰好是由模板成员生成的。

【讨论】:

  • 示例中似乎缺少一些强类型概念。使用带有类型的模板会产生新的类型,您的 foo 可以有 A* x = new A(true); 或 A* y = new A(123); 与 x 和 y 最终为同一类型
  • @infixed 'foo' 不是构造函数,因此您的示例代码不适用。这个问题专门针对具有模板成员函数的非模板类。没有创建新类型。
【解决方案2】:

模板类定义在你实例化一个类时被实例化。它的每个成员函数在使用时都会被实例化。这实际上允许您拥有在使用某些类型而不是其他类型实例化类时调用的成员函数。但是,您必须确保函数的 签名 在语法上是可行的,或者在 SFINAE 中失败。它将在解析的第一阶段进行查找。如果函数本身不是模板,则主体将检查名称查找...因此必须通过 typename 将依赖名称标记为此类。

【讨论】:

  • 我认为这不太对。没有“模板类定义”之类的东西。有一个类模板定义,但它从未被实例化。仅实例化模板的特化。此外,不会在每次使用时都实例化特化,而只会在第一次使用时(在每个翻译单元内)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-02
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多