我有一个带有成员模板功能的类:
// 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.expl.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)
{ /* ... */ }
您也可以只在标头中声明它(不再需要内联),而仍在源代码中定义它。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句