未调用模板化函数

Templated function not called

我在我的字符串 class 中重载了一个函数,但是,它从未被调用过。为什么?

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])
}

当有选择时,编译器会选择最专业的函数。当存在非模板函数时,它被视为比任何模板函数都更专业

详情here

如果你想保留非模板函数但强行调用模板,试试看

str.template assign("Hello World");

为了获得更多参考,对标准的一些具体参考是:

13.3.3 Best viable function

Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then...

  • F1 is not a function template specialization and F2 is a function template specialization...

在这种情况下,非模板函数(显然)不是函数模板特化,"Hello World"char const* 的转换并不比 const char[N] 差,per “标准转换序列”部分的 Table 中定义的排名规则。根据 Table,No conversions requiredArray-to-pointer conversion 在重载解析的上下文中都被认为是完全匹配。同样,如果模板化重载更改为非模板重载(即 void assign(const T(&ptr)[12]);),则 str.assign("Hello World"); 的编译将因调用不明确而失败。

为确保非模板函数不被考虑重载,在“显式模板参数规范”部分下有以下注释:

Note: An empty template argument list can be used to indicate that a given use refers to a specialization of a function template even when a non-template function (8.3.5) is visible that would otherwise be used.

因此,您可以使用 str.assign<>("Hello World");