简体   繁体   English

如果一个函数定义有一个类模板类型的参数并且没有使用它(它的成员),那么它是否被实例化?

[英]If a function definition has a parameter of class template type and didn't use it (its members) then is it instantiated?

From the previous example I've posted here about when the template is instantiated?从上一个示例中,我在这里发布了有关何时实例化template的信息? , I got the answer that only when a template is used the compiler instantiates it. ,我得到的答案是,只有在使用模板时,编译器才会实例化它。 But look at this example:但是看看这个例子:

template <typename T>
struct Pow{
    T operator()(T const& x){ return x * x; }
};

extern template struct Pow<int>; // explicit instantiation declaration

struct Foo{
    Pow<int> pi{};
    void fn(Pow<int>);
};
void Foo::fn(Pow<int> pw){
   // std::cout << pw(7) << '\n';
}

void bar(Pow<int> pwi){
    // std::cout << pwi(10) << '\n';
}

int main(){
    Foo f;
}
  • As you can see I've declared an explicit template instantiation Pow<int> but haven't defined it.如您所见,我已经声明了一个显式模板实例化Pow<int>但尚未定义它。 The program works just fine and doesn't complain about the missing definition of Pow<int> !该程序运行良好,并且不会抱怨缺少Pow<int>定义!

  • In the previous topic I've been answered if I use a template type as a type of parameter for a function definition (not declaration) then the template is instantiated but here as you can see: The member function Foo::fn(Pow<int>) and the ordinary function function bar(Pow<int>) are defined but the compiler doesn't complain about the definition of Pow<int> ?!!!在上一个主题中,如果我使用模板类型作为函数定义(不是声明)的参数类型,那么模板将被实例化,但在这里您可以看到:成员函数Foo::fn(Pow<int>)和普通函数函数bar(Pow<int>)被定义了但是编译器没有抱怨Pow<int>的定义?!!!

  • The program fails to compile if I un-comment the lines in the aforementioned functions.如果我取消注释上述函数中的行,程序将无法编译。 so does it mean that Pow<int> is not instantiated when used as function parameter in the function definition and as member data like in Foo::Pow<int> pi{};这是否意味着Pow<int>在用作函数定义中的函数参数和像Foo::Pow<int> pi{};成员数据时不会被实例化Foo::Pow<int> pi{}; ? ?

  • I find it confusing:我觉得很困惑:

     void f(Pow<int>); // function declaration: Pow<int> is not instantiated yet. void f2(Pow<int>){} // function definition: Pow<int> instantiated? void f3(pow<int> Pwi){ std::cout << Pwi(10);} // function definition and usage of `Pow<int>`: Pow<int> instantiated?
  • In main:在主要:

     Foo f; // f has pi of type Pow<int>. so Pow<int> is instantiated?

Pow<int> is defined. Pow<int>定义。 It is defined as Pow<T> with T=int .它被定义为Pow<T>T=int

The program works just fine and doesn't complain about the missing definition of Pow<int> !该程序运行良好,并且不会抱怨缺少Pow<int>定义!

Because it isn't missing.因为它不缺。 Both forms of explicit instantiation (declaration and definition) cause the instantiation of class templates.显式实例化的两种形式(声明和定义)都会导致类模板的实例化。 An explicit instantiation definition causes the instantiation of member functions (which are normally instantiated lazily only when needed).显式实例化定义会导致成员函数的实例化(通常仅在需要时才延迟实例化)。 On the other hand, an explicit instantiation declaration will suppress the implicit instantiation of a member function.另一方面,显式实例化声明抑制成员函数的隐式实例化。 Even if that member function body is visible!即使那个成员函数体是可见的!

It's a tool to write templates for a constrained set of types, while hiding their implementation.它是一种为一组受约束的类型编写模板的工具,同时隐藏它们的实现。 It allows one to do this:它允许一个人这样做:

//pow.h

template <typename T>
struct Pow{
    T operator()(T const& x); // Just a declaration 
};

extern template struct Pow<int>; // The class is instantiated, the member is 
                                 // assumed to be explicitly instantiated elsewhere

//pow.cpp
#include "pow.h"

template <typename T>
T Pow<T>::operator()(T const& x) { return x * x; }

template struct Pow<int>; // Explicit instantiation. The member function is defined
                          // in **this** translation unit.

And that is exactly why your program fails to link.这正是您的程序无法链接的原因。 The member operator() is never instantiated anywhere in your program.成员operator()永远不会在您的程序中的任何地方实例化。 You can fix it by providing an explicit instantiation definition somewhere.您可以通过在某处提供显式实例化定义来修复它。 For instance例如

template <typename T>
struct Pow{
    T operator()(T const& x){ return x * x; }
};

// ...

int main() {
// ...
}

template struct Pow<int>; // Now the member function is emitted

Another use of this can be to potentially improve compile times.另一个用途是潜在地改进编译时间。 If you have a class template that you know is often instantiated for a specific set of types, you can help the linker along.如果你有一个类模板,你知道通常实例化一组特定的类型,可以帮助沿着连接器。

// my_string.h

template<typename charT>
class my_string {
  // Everything, members and all
};

extern template class my_string<char>;
extern template class my_string<wchar_t>;

// my_string.cpp 

#include <my_string.h>

// This file can be part of a shared object that ships with your library
// The common declarations are here

template class my_string<char>;
template class my_string<wchar_t>;

Now the linker doesn't have to sort the many duplicate symbols that would have been produced by implicit instantiation of the commonly used my_string<char> and my_string<wchar_t> .现在,链接器不必对由常用my_string<char>my_string<wchar_t>的隐式实例化产生的许多重复符号进行排序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在实例化类时是否实例化了类模板的成员? - Are members of a class template instantiated when the class is instantiated? 在其定义中使用类模板 - use class template in its definition 为什么未调用的模板类成员未实例化? - Why uncalled template class members aren't instantiated? 如何定义一个模板 function,它只接受一个基类 class,参数 T 是它的子类? - How to define a template function that only accepts a base class with parameter T of type its subclass? 类模板,在定义中引用自己的类型 - class template, referring to its own type in definition 是否可以检查类型是否已使用特定模板参数实例化? - Is it possible to check if a type has been instantiated with a specific template parameter? 是否可以使用“if constexpr”来确定是否可以使用特定类型参数实例化模板函数? - Is it possible to use 'if constexpr' to determine if a template function could be instantiated with a particular type parameter? 使用模板template参数作为类函数的返回类型 - Use template template parameter as return type of class function 为什么未调用的模板类成员*参数*被实例化? - Why uncalled template class members *parameters* ARE instantiated? 可以在没有成员的情况下实例化类模板吗? - Class template can be instantiated without members?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM