gpt4 book ai didi

c++ - 源文件中成员函数模板的显式特化

转载 作者:可可西里 更新时间:2023-11-01 15:54:51 24 4
gpt4 key购买 nike

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

// 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 中的打油诗的帮助下,标准强烈建议您不要这样做:

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.

在某些翻译单元中,特化很可能恰好在首次使用之前声明 - 而在某些翻译单元中则没有。最好通过简单地在标题中声明您的特化来完全避免所有此类问题:

// 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++ - 源文件中成员函数模板的显式特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30530364/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com