gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 14:02:07 27 4
gpt4 key购买 nike

从我在此处发布的关于 when the template is instantiated? 的先前示例中,我得到的答案是只有在使用模板时编译器才会实例化它。但是看看这个例子:

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;
}
  • 如您所见,我已经声明了一个显式模板实例化 Pow<int>,但还没有定义它。该程序运行良好,不会提示缺少 Pow<int> 的定义!

  • 在上一个主题中,如果我使用模板类型作为函数定义(而不是声明)的参数类型,那么模板将被实例化,但您可以在此处看到:成员函数 Foo::fn(Pow<int>)和普通函数 function bar(Pow<int>) 被定义但是编译器没有提示 Pow<int> 的定义 ?!!!

  • 如果我取消注释上述函数中的行,程序将无法编译。那么这是否意味着 Pow<int> 在用作函数定义中的函数参数和像 Foo::Pow<int> pi{}; 中的成员数据时没有被实例化?

  • 我觉得很困惑:

    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?
  • 主要内容:

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

最佳答案

The program works just fine and doesn't complain about the missing definition of Pow<int>!

因为它没有丢失。显式实例化的两种形式(声明和定义)都会导致类模板的实例化。显式实例化定义会导致成员函数的实例化(通常仅在需要时才延迟实例化)。另一方面,显式实例化声明抑制成员函数的隐式实例化。即使那个成员函数体是可见的!

它是一种为一组受限类型编写模板,同时隐藏其实现的工具。它允许人们这样做:

//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.

这正是您的程序无法链接的原因。成员(member)operator()永远不会在您的程序中的任何地方实例化。您可以通过在某处提供显式实例化定义来修复它。例如

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

它的另一个用途是潜在地改进编译时间。如果您有一个您知道经常为一组特定类型实例化的类模板,您可以帮助链接器。

// 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>;

现在,链接器不必对常用 my_string<char> 的隐式实例化产生的许多重复符号进行排序。和 my_string<wchar_t> .

关于c++ - 如果一个函数定义有一个类模板类型的参数并且没有使用它(它的成员)那么它是否被实例化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69653208/

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