Would it be possible to explain why the following code ain't working as expected? In this case, I would assume that both static_asserts would pass, though the one indicated with Failed
doesn't seem to be taken.
My understanding of overload resolution would be that the type most closely linked to the argument. As the top definition is a C-Style array, while the bottom definition is a decayed char*; I find it strange that the select overload gets used.
Both MSVC as Clang seem to have the same behavior.
error: static_assert expression is not an integral constant expression
note: non-constexpr function 'getStrLen' cannot be used in a constant expression
The code:
template<size_t N>
constexpr auto getStrLen(const char(&str)[N])
{
static_assert(N != 0, "Every literal string should have a null terminator");
return N - 1; // Remove \0
}
static_assert(getStrLen("") == 0, "Success");
auto getStrLen(const char *str)
{
return strlen(str);
}
static_assert(getStrLen("") == 0, "Failed");
An exact match and array to pointer conversion have the same rank according to 16.3.3.1.1 [over.ics.scs]/Table 13. A matching non-template
is preferred over a matching template
according to 16.3.3 [over.best.match]. In summary, the non-template function taking a char const*
is the better match.
Making this function a template
, e.g., by giving it a defaulted template
parameter may solve the problem. It has a fair chance to make the two function ambiguous.