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

时间:2012-10-25 12:49:18

标签: c++ templates explicit-instantiation

我刚读过模板显式实例化:

template struct MyStruct<long>;

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

4 个答案:

答案 0 :(得分:12)

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

<强> tpl.h

template<typename T>
void func(); // Declaration

<强> tpl.cpp

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

template void func<int>(); // explicit instantiation for int
template void func<double>();  // explicit instantiation for double

<强>的main.cpp

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

答案 1 :(得分:7)

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

当您想要封装模板实现并且您希望此模板仅用于众所周知的类型集时,显式实例化也很有用。在这种情况下,您只能在头文件(.h/.hpp)中放置模板函数(免费或成员)的声明,并在翻译单元(.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
   ...
 }

当您需要从模板实例化类型但在某些语法结构中不会触发实例化本身时,显式实例化也很有用,例如:一些特定于编译器的元功能,如__declspec(uuid) in 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       
   ...
 }

答案 2 :(得分:5)

具有明确的专业化允许您隐藏实现,如您所知,通常无法使用模板。

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

所以你可以使用

lib::Vector<MyShape>

具有lib::Vector提供的一些基本功能和基本实现,如果您将它与其类(一些,而不是全部)一起使用

lib::Vector<lib::Polygon>

你会使用显式专业化。您无权访问该实现,但我认为在那里幕后会进行一些硬核优化。

答案 3 :(得分:0)

如果您真的不喜欢在头文件中定义模板函数,可以在单独的源文件中定义函数,并使用显式模板实例化来实例化您使用的所有版本。然后,您只需要在头文件中使用前向声明而不是完整定义。