模板成员函数如何在 C++ 中工作?
How do template member functions work in c++?
我想知道模板成员函数是如何工作的。特别是当有模板成员函数的实例化时,是不是整个class都重新定义了?我的困惑来自于这样一个事实,即(如果我是对的)模板 classes 不是正确意义上的 classes。即,在实例化时,编译器会为一个全新的 class 创建定义。模板函数也一样。但是,带有模板函数的 classes 似乎是实际的 classes,所以我不确定它们如何工作。因此,我想知道,在实例化模板成员函数之后,class 定义会发生什么?此外,如果我将带有模板成员函数的class传递给模板class,我可以使用模板成员函数吗?这会导致问题吗?我尝试了一次,但出现错误,说有几个函数定义了不止一次,尽管我不确定这是否是原因,或者是否有其他原因导致我的错误。使用静态模板成员函数时还有什么注意事项吗?
class定义保持原样;模板函数所做的就是为 class 生成一个成员函数族。例如:
class A {
public:
template<typename T> foo (T &t);
}
在概念上与你写的没有区别:
class A {
public:
foo (bool &t);
foo (int &t);
foo (double &t);
}
...只是更方便。在最后一个示例中,您不会期望为每个函数创建一个新的 class 吧?
也许混淆来自这样一种观念,即函数在某种程度上是 class 内存布局的一部分;每个函数本身都包含在 class 中,并且只要创建 class 的对象,就会在内存中的某个地方实例化。这种观念是不正确的。函数(模板函数、全局函数、成员函数、lambda 函数或其他函数)永远不会即时创建或在内存中复制;它们是可执行映像的静态且不变的部分。 class 的内存布局不会因一组额外函数的存在而改变,即使这些函数恰好是由模板成员生成的。
模板 class 定义在实例化 class 时实例化。它的每个成员函数在使用时都被实例化。这实际上允许您拥有在 class 以某些类型而不是其他类型实例化时调用的成员函数。但是,您必须确保函数的 signature 在句法上是可行的,否则会因 SFINAE 而失败。它将在解析的第一阶段进行查找。正文,如果函数本身不是模板,将检查名称查找...因此必须通过类型名称标记依赖名称。
我想知道模板成员函数是如何工作的。特别是当有模板成员函数的实例化时,是不是整个class都重新定义了?我的困惑来自于这样一个事实,即(如果我是对的)模板 classes 不是正确意义上的 classes。即,在实例化时,编译器会为一个全新的 class 创建定义。模板函数也一样。但是,带有模板函数的 classes 似乎是实际的 classes,所以我不确定它们如何工作。因此,我想知道,在实例化模板成员函数之后,class 定义会发生什么?此外,如果我将带有模板成员函数的class传递给模板class,我可以使用模板成员函数吗?这会导致问题吗?我尝试了一次,但出现错误,说有几个函数定义了不止一次,尽管我不确定这是否是原因,或者是否有其他原因导致我的错误。使用静态模板成员函数时还有什么注意事项吗?
class定义保持原样;模板函数所做的就是为 class 生成一个成员函数族。例如:
class A {
public:
template<typename T> foo (T &t);
}
在概念上与你写的没有区别:
class A {
public:
foo (bool &t);
foo (int &t);
foo (double &t);
}
...只是更方便。在最后一个示例中,您不会期望为每个函数创建一个新的 class 吧?
也许混淆来自这样一种观念,即函数在某种程度上是 class 内存布局的一部分;每个函数本身都包含在 class 中,并且只要创建 class 的对象,就会在内存中的某个地方实例化。这种观念是不正确的。函数(模板函数、全局函数、成员函数、lambda 函数或其他函数)永远不会即时创建或在内存中复制;它们是可执行映像的静态且不变的部分。 class 的内存布局不会因一组额外函数的存在而改变,即使这些函数恰好是由模板成员生成的。
模板 class 定义在实例化 class 时实例化。它的每个成员函数在使用时都被实例化。这实际上允许您拥有在 class 以某些类型而不是其他类型实例化时调用的成员函数。但是,您必须确保函数的 signature 在句法上是可行的,否则会因 SFINAE 而失败。它将在解析的第一阶段进行查找。正文,如果函数本身不是模板,将检查名称查找...因此必须通过类型名称标记依赖名称。