C++ 源文件中成员函数模板的显式专门化

C++ 源文件中成员函数模板的显式专门化,c++,templates,explicit-specialization,C++,Templates,Explicit Specialization,我有一个带有成员模板函数的类: // writer.h class Writer { public: ... template <typename T, typename V> void addField(const std::string& name, V v) { // write something } }; 这很有效。。。有时候。即使我确定我有正确的类型: writer.addField<some_ty

我有一个带有成员模板函数的类:

// writer.h
class Writer {
public:
    ...
    template <typename T, typename V>
    void addField(const std::string& name, V v) 
    {
        // write something
    }
};
这很有效。。。有时候。即使我确定我有正确的类型:

writer.addField<some_type>("name", static_cast<int>(some_value));
writer.addField(“name”,静态_cast(某些值));

有时调用显式专用化,有时调用主专用化。有什么好处?

在源文件中声明专门化,可能会导致各种难以诊断的微妙问题。编译器也没有义务在任何方面帮助您。标准强烈鼓励您不要在[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)
{ /* ... */ }
//writer.h
班主任{
公众:
...
模板
void addField(const std::string&name,V)
{ /* ... */ }
};
//仍然是作家
模板
内联void Writer::addField(const std::string&name,int v)
{ /* ... */ }

您也可以只在标题中声明它(不再需要内联),并且仍然在源代码中定义它。

如果它在标题中,您需要使它
内联
;或者,您可以在标题中声明专门化,并在其他地方定义它。@T.C.啊,哎呀。我完全忽略了。在Visual Studio下,它是一个编译器错误:。
// 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)
{ /* ... */ }