我在我的字符串类中重载了一个函数,然而,它永远不会被调用。为什么呢?
template <class T>
class StringT {
public:
void assign(const T* ptr);
template <size_t N> void assign(const T(&ptr)[N]);
};
int main() {
StringT<char> str;
str.assign("Hello World"); //calls "void assign(const T* ptr)" although type is (const char[12])
}
答案 0 :(得分:6)
有关更多参考,标准的一些具体参考是:
13.3.3最佳可行功能
鉴于这些定义,可行函数F1被定义为比另一个可行函数F2更好的函数,如果对于所有自变量i,ICSi(F1)不是比ICSi(F2)更差的转换序列,然后......
- F1不是功能模板专业化,F2是功能模板专业化......
在这种情况下,非模板化函数(显然)不是函数模板特化,而"Hello World"
到char const*
的转换并不比const char[N]
更差,按照排名“标准转换序列”部分的表中定义的规则。根据该表,No conversions required
和Array-to-pointer conversion
在重载解析的上下文中被认为是完全匹配。同样,如果模板化的重载更改为非模板重载(即void assign(const T(&ptr)[12]);
),则str.assign("Hello World");
的编译将因调用模糊而失败。
为了确保不考虑非模板函数的重载,在“显式模板参数规范”部分下面有以下注释:
注意:空模板参数列表可用于指示给定用途是指函数模板的特化,即使非模板函数(8.3.5)可见,否则将被使用。
因此,您可以使用str.assign<>("Hello World");
。
答案 1 :(得分:3)
当有选择时,编译器会选择最专业的功能。当存在非模板函数时,它被视为比任何模板函数更专业化
详情here
如果您想保留非模板功能但强行调用模板,请尝试
str.template assign("Hello World");