For more information, some specific references to the standard:
13.3.3 Best Viable Function
Given these definitions, a viable function F1 is defined as 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 specialized template, and F2 is not a specialized template function ...
In this case, the non-template function (obviously) is not a specialized template function, and the conversion of "Hello World" to char const* no worse than const char[N] , for the ranking rules defined in the table in the section "Standard conversion sequences" . According to this table, both No conversions required and Array-to-pointer conversion are considered exact matches in the context of overload resolution. Similarly, if template overloads are changed to overload without a template (ie Like void assign(const T(&ptr)[12]); ), compilation str.assign("Hello World"); will fail due to an ambiguous call.
To ensure that the non-template function is not considered for overloading, there is the following note in the "Explicit Specification of Template Arguments" section:
Note. The list of empty templates can be used to indicate that this use is related to the specialization of a function template, even if a function without a template is visible (8.3.5), which would otherwise be used.
So you can use str.assign<>("Hello World"); for this.
source share