我刚刚阅读了有关模板显式实例化的内容:
template struct MyStruct<long>;
它被描述为“非常罕见”,那么它在什么情况下会有用呢?
我刚刚阅读了有关模板显式实例化的内容:
template struct MyStruct<long>;
它被描述为“非常罕见”,那么它在什么情况下会有用呢?
用例之一是对最终用户隐藏定义。
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
主文件
#include "tpl.h"
int main()
{
func<double>(); // OK
func<int>(); // OK
// func<char>(); - Linking ERROR
}
显式实例化旨在优化模板库的使用,以编译的二进制形式而不是源代码形式提供一些(最常用的)模板实例。这将减少最终用户应用程序的编译和链接时间。例如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)
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
...
}
具有显式特化允许您隐藏实现,如您所知,使用模板通常是不可能的。
我在处理几何的库中只见过一次这种技术,他们会提供自己的矢量类。
所以你可以使用
lib::Vector<MyShape>
具有提供的一些基本功能lib::Vector
和基本实现,如果您将其与他们的类一起使用(一些,不是全部)
lib::Vector<lib::Polygon>
您将使用显式专业化。您将无法访问该实现,但我敢打赌,那里的幕后正在进行一些核心优化。
如果您真的不喜欢在头文件中定义模板函数,您可以在单独的源文件中定义函数,并使用显式模板实例化来实例化您使用的所有版本。然后,您只需要在头文件中进行前向声明,而不是完整的定义。