vendredi 20 décembre 2019

How to make a template re-deduce a const char[N] "mychar" which already had decayed to const char*?

I have this code I took from __FILE__ macro manipulation handling at compile time:

#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)

constexpr const char * const strend(const char * const str) {
    return *str ? strend(str + 1) : str;
}

constexpr const char * const fromlastslash(const char * const start, const char * const end) {
    return (end >= start && *end != '/' && *end != '\\') ? fromlastslash(start, end - 1) : (end + 1);
}

constexpr const char * const pathlast(const char * const path) {
    return fromlastslash(path, strend(path));
}

int constexpr length(const char* str) {
    return *str ? 1 + length(str + 1) : 0;
}

int main(int argc, char const *argv[])
{
    constexpr const char* myExpression = pathlast( "cppdebugger/test_debugger.cpp" );
    STATIC_ASSERT( length(myExpression) == 17 );
}

Which works fine. But instead of using the constexpr length(const char* str) recursive function, I would like to use this other one (length( char const (&)[N] )), which deduces the const char[] size by while decaying it to const char*. I am using clang do expand the template only instead of building it:

/usr/bin/clang++ -Xclang -ast-print -fsyntax-only test_debugger.cpp > main.exe

template< unsigned int N >
constexpr unsigned int length( char const (&)[N] )
{
  return N-1;
}

However, it is clearly not liking to receive a const char*:

test_debugger.cpp:25:20: error: no matching function for call to 'length'
    static_assert( length(myExpression) == 17, "not equal to test_debugger.cpp" );
                   ^~~~~~
test_debugger.cpp:17:24: note: candidate template ignored: could not match 'const char [N]' against 'const char *const'
constexpr unsigned int length( char const (&)[N] )
                       ^
1 error generated.

Is there a way I can pass the const char* string with length( char const (&)[N] )?

Aucun commentaire:

Enregistrer un commentaire