Explicit specialization of member function template in source file

后端 未结 1 2170
执念已碎
执念已碎 2020-12-30 09:55

I have a class with a member template function:

// writer.h
class Writer {
public:
    ...
    template 
    void addField(cons         


        
相关标签:
1条回答
  • 2020-12-30 10:35

    Declaring specializations in a source file and can cause all sorts of subtle issues that are very difficult to diagnose. The compiler isn't obligated to help you in any regard here either. The standard strongly encourages you not to do this, with the help of a limerick, in [temp.expl.spec]/6-7:

    If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required. If the program does not provide a definition for an explicit specialization and either the specialization is used in a way that would cause an implicit instantiation to take place or the member is a virtual member function, the program is ill-formed, no diagnostic required. An implicit instantiation is never generated for an explicit specialization that is declared but not defined.

    The placement of explicit specialization declarations for function templates, class templates, variable templates, member functions of class templates, [...], etc., can affect whether a program is well-formed according to the relative positioning of the explicit specialization declarations and their points of instantiation in the translation unit as specified above and below. When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation.

    It's likely that in some translation units, the specialization happened to be declared before the first use - and in some translation units it hasn't been. It's better to avoid all such issues entirely by simply declaring your specialization in your header:

    // 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)
    { /* ... */ }
    

    You can also just declare it in the header (no longer needs to be inline), and still define it in the source.

    0 讨论(0)
提交回复
热议问题