我正在尝试使用this post中描述的方法修复“非命名空间作用域中的显式特化”错误。所以我设法将模板化的函数移动到一个单独的命名空间中,我从我的类中调用这些函数(参见下面的代码)。
代码现在编译,但是我在命名空间中的所有函数中“已经在main.obj中定义了链接器错误”。我认为在顶部添加#ifndef STYLE_H
会阻止命名空间被多次包含,或者我错过了什么?我该如何解决这个错误?
以下是我的代码(简化):
#ifndef STYLE_H
#define STYLE_H
namespace hanzi {
namespace styleUtil {
template <class T>
T get(const QString& name, T defaultValue = T(), const Style* style = NULL, const Style* baseStyle = NULL) {
// ...
}
template <>
QColor get<QColor>(const QString& name, QColor defaultValue, const Style* style, const Style* baseStyle) {
// ...
}
template <>
ImagingEffect get<ImagingEffect>(const QString& name, ImagingEffect defaultValue, const Style* style, const Style* baseStyle) {
// ...
}
}
class Style : public QObject {
Q_OBJECT
public:
explicit Style(const QString& filePath);
template <class T>
T get(const QString& name, T defaultValue = T()) const {
return styleUtil::get<T>(name, defaultValue, this, baseStyle_);
};
};
}
#endif // STYLE_H
答案 0 :(得分:2)
关于原始错误,
我正在尝试修复“非命名空间范围内的显式特化”错误
该错误意味着您无法在类定义中定义成员函数模板特化。即以下是非法的:
struct Bar
{
template <typename T> void boo() { }
// template <> void boo<char>() { boo<int>(); } // Error! Cannot specialize here
};
但是,只需将专门化放在类定义中即可解决此问题:
template <> void Bar::boo<char>() { boo<int>(); } // Good.
(专业化的后一个位置是“在命名空间范围内”,例如在全局范围内,这是错误消息想要告诉你的事情。)
答案 1 :(得分:2)
功能模板的完全专业化不再是模板:它是一个功能。
因此,当您在标题中定义它时,您需要添加关键字inline
。
inline
改变了C ++&#34;一个定义规则&#34;的行为。 (ODR)。基本上,对于inline
,必须在每个使用它的翻译单元中定义该函数,并且这些定义必须实际上相等。两者都是通过将定义放在头文件中来实现的。
inline
也可以作为优化提示,但第二种含义并不能保证。
另请注意,所以这个答案不会误导你,没有功能模板的部分特化。