简体   繁体   中英

Overload resolution C-style strings

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 , eg, by giving it a defaulted template parameter may solve the problem. It has a fair chance to make the two function ambiguous.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM