源文件中成员函数模板的显式专业化 [英] Explicit specialization of member function template in source file

查看:130
本文介绍了源文件中成员函数模板的显式专业化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有成员模板功能的类:

I have a class with a member template function:

// writer.h
class Writer {
public:
    ...
    template <typename T, typename V>
    void addField(const std::string& name, V v) 
    {
        // write something
    }
};

在Writer的源文件中,我为some_type添加了显式的专业化:

And in Writer's source file, I added explicit specializations for some_type:

// writer.cpp
template <>
void Writer::addField<some_type, int>(const std::string& name, int v)
{
    // specific some_type writing logic
}

这可行...有时.即使我绝对确保我拥有正确的类型:

This works... sometimes. Even if I definitely make sure that I have the right types:

writer.addField<some_type>("name", static_cast<int>(some_value));

有时会调用显式专业化,有时会调用主专业.有什么作用?

Sometimes the explicit specialization gets called, and sometimes the primary gets called. What gives?

推荐答案

在源文件中声明特殊化,可能会导致各种难以诊断的细微问题.编译器也没有义务在任何方面为您提供帮助.在[temp.expl.spec]/6-7中,标准强烈鼓励您不要这样做(在打油诗的帮助下)

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.

这篇关于源文件中成员函数模板的显式专业化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆