你什么时候使用模板显式实例化?

Mar*_*ram 19 c++ templates explicit-instantiation

我刚刚阅读有关模板显式实例化的内容:

template struct MyStruct<long>;

它被描述为"非常罕见",所以它在什么情况下会有用?

Evg*_*yuk 12

其中一个用例是隐藏最终用户的定义.

tpl.h:

template<typename T>
void func(); // Declaration
Run Code Online (Sandbox Code Playgroud)

tpl.cpp:

template<typename T>
void func()
{
    // Definition
}

template void func<int>(); // explicit instantiation for int
template void func<double>();  // explicit instantiation for double
Run Code Online (Sandbox Code Playgroud)

main.cpp中

#include "tpl.h"
int main()
{
    func<double>(); // OK
    func<int>(); // OK
    // func<char>(); - Linking ERROR
}
Run Code Online (Sandbox Code Playgroud)


Ros*_*ost 7

显式实例化旨在优化模板库的使用,以编译的二进制形式提供一些(大多数使用的)模板实例,而不是源代码形式.这将减少最终用户应用程序的编译和链接时间.例如std::basic_string<char>,std::basic_string<wchar_t>可以在STL分发中明确地实例化,避免在每个翻译单元中对其实例化进行处理.

当您想要封装模板实现并且希望此模板仅用于众所周知的类型集时,显式实例化也很有用.在这种情况下,您只能在头文件(.h/.hpp)中放置模板函数(free或members)的声明,并在translation unit(.cpp)中定义它们.

例:

 // numeric_vector.h
 //////////////////////////////////////////////////
 template <typename T> class numeric_vector
 {
    ...
    void sort();
 };


 // numeric_vector.cpp
 //////////////////////////////////////////////////
 // We know that it shall be used with doubles and ints only,
 // so we explicitly instantiate it for doubles and ints
 template class numeric_vector<int>;
 template class numeric_vector<double>;

 // Note that you could instantiate only specific
 // members you need (functions and static data), not entire class:
 template void numeric_vector<float>::sort();

 template <typename T> void numeric_vector<T>::sort()
 {
   // Implementation
   ...
 }
Run Code Online (Sandbox Code Playgroud)

当您需要从模板实例化类型但在一些不触发实例化的语法结构内部时,显式实例化也很有用,例如某些特定__declspec(uuid)编译器的元特征,如Visual Studio中.

注意与可用于实现封装的另一种技术的区别 - 显式特化.使用显式特化,您必须为每个要专门化的类型提供特定的定义.通过显式实例化,您可以使用单个模板定义.

考虑具有显式特化的相同示例:

例:

 // numeric_vector.h
 //////////////////////////////////////////////////
 template <typename T> class numeric_vector
 {
    ...
    void sort();
 };

 template <> class numeric_vector<int>
 {
    ...
    void sort();
 };

 template <> class numeric_vector<double>
 {
    ...
    void sort();
 };

 // Specializing separate members is also allowed
 template <> void numeric_vector<float>::sort();

 // numeric_vector.cpp    
 //////////////////////////////////////////////////
 void numeric_vector<int>::sort()
 {
   // Implementation for int
   ...
 }

 void numeric_vector<double>::sort()
 {
   // Implementation for double
   ...
 }

 void numeric_vector<float>::sort()
 {
   // Implementation for float       
   ...
 }
Run Code Online (Sandbox Code Playgroud)


Luc*_*ore 5

具有明确的专业化允许您隐藏实现,如您所知,通常不可能使用模板.

我在处理几何的库中只看过一次这种技术,他们提供了自己的矢量类.

所以你可以使用

lib::Vector<MyShape>
Run Code Online (Sandbox Code Playgroud)

提供了一些基本功能lib::Vector和基本实现,如果你将它与它们的类一起使用(一些,不是全部)

lib::Vector<lib::Polygon>
Run Code Online (Sandbox Code Playgroud)

你会使用显式专业化.你无法访问实现,但我打赌一些硬核优化正在幕后进行.