成员函数模板在源文件中的显式特化
Explicit specialization of member function template in source file
我有一个带有成员模板函数的类:
// writer.h
class Writer {
public:
...
template <typename T, typename V>
void addField(const std::string& name, V v)
{
// write something
}
};
在Writer的源文件中,我为some_type
添加了显式专门化:
// writer.cpp
template <>
void Writer::addField<some_type, int>(const std::string& name, int v)
{
// specific some_type writing logic
}
这工作…有时。即使我确定我有正确的类型:
writer.addField<some_type>("name", static_cast<int>(some_value));
有时调用显式专门化,有时调用主专门化。到底发生了什么事? 在源文件中声明专门化可能会导致各种难以诊断的微妙问题。编译器也没有义务在任何方面帮助您。标准强烈建议您不要这样做,在打油诗的帮助下,在[temp.exp .spec]/6-7:
如果模板、成员模板或类模板的成员被显式特化,则该特化应该在第一次使用可能导致隐式实例化的专门化之前声明在发生这种使用的每个翻译单元中,发生;不需要诊断。如果程序没有为显式专门化提供定义,或者以某种方式使用专门化这将导致隐式实例化发生,或者该成员是虚成员函数程序格式不正确,不需要诊断。永远不会为显式实例生成隐式实例已声明但未定义的专门化。
函数模板、类模板、变量模板、类模板的成员函数,[…]]等,会影响程序的格式是否良好到显式专门化声明及其实例化点的相对位置在上面和下面指定的翻译单元中。在编写专门化时,要注意它的位置;或者让它编译将是一种考验,从而点燃它的自焚。
很可能在一些翻译单元中,专门化碰巧在第一次使用之前被声明,而在一些翻译单元中则没有。最好通过在头文件中声明专门化来完全避免所有这些问题:
// writer.h
class Writer {
public:
...
template <typename T, typename V>
void addField(const std::string& name, V v)
{ /* ... */ }
};
// still writer.h
template <>
inline void Writer::addField<some_type, int>(const std::string& name, int v)
{ /* ... */ }
你也可以只在header中声明它(不再需要内联),并且仍然在源代码中定义它。
相关文章:
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 将重载的成员函数传递给函数模板
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 具有常量引用参数的函数模板专用化
- std::span<const T> 作为函数模板中的参数
- 如何编写一个完美的缩写函数模板?
- 仅在函数模板中为那些定义了函数的类型执行函数
- 如何在C++中伪造虚拟可变参数函数模板?
- 以下代码中的函数模板有什么问题?
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 将显式实例化的函数模板与转换匹配
- 使用定义函数模板别名
- 函数模板返回类型
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- C++ std::functional 中的可变参数函数模板
- 单行函数模板 c++ 的内联性保证
- C++函数模板需要 &for 数组参数
- 概念解析为使用 std::make_signed_t 时意外的函数模板
- 成员函数模板在源文件中的显式特化