mardi 24 décembre 2019

Why I cannot partially specialize template functions, only classes?

I could find some questions asking about why I cannot specialize member functions:

  1. Why can't you partially specialize a class member function?
  2. Partially specializing member-function implementations
  3. why cannot partially specialize a member function, in c++ template

But why I cannot partially specialize a loose functions?

#include <array>
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)

template< int PathIndex, int PathLength >
constexpr const int findlastslash(const char (&path)[PathLength])
{
    constexpr const int end = PathLength - PathIndex;
    return (PathIndex >= 0 && path[end] != '/' && path[end] != '\\') 
            ? findlastslash< PathIndex - 1, PathLength >( path ) : ( end + 1 );
}

template< int PathLength >
constexpr const int findlastslash< 1, PathLength >(const char (&path)[PathLength]);

template< int PathLength >
constexpr const int startfindlastslash(const char (&path)[PathLength]) {
    return findlastslash< PathLength >( path );
}

int main(int argc, char const *argv[])
{
    STATIC_ASSERT( startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 17 );
}
$ g++ -o main.exe --std=c++14 test_debugger.cpp
test_debugger.cpp:12:82: error: non-class, non-variable partial specialization ‘findlastslash<1, PathLength>’ is not allowed
 constexpr const int findlastslash< 1, PathLength >(const char (&path)[PathLength]);
                                                                                  ^
test_debugger.cpp: In instantiation of ‘constexpr const int startfindlastslash(const char (&)[PathLength]) [with int PathLength = 30]’:
test_debugger.cpp:21:5:   required from here
test_debugger.cpp:16:39: error: call of overloaded ‘findlastslash<30>(const char [30])’ is ambiguous
     return findlastslash< PathLength >( path );
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
test_debugger.cpp:5:21: note: candidate: constexpr const int findlastslash(const char (&)[PathLength]) [with int PathIndex = 30; int PathLength = 30]
 constexpr const int findlastslash(const char (&path)[PathLength])
                     ^~~~~~~~~~~~~
test_debugger.cpp:12:21: note: candidate: constexpr const int findlastslash(const char (&)[PathLength]) [with int PathLength = 30]
 constexpr const int findlastslash< 1, PathLength >(const char (&path)[PathLength]);
                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test_debugger.cpp: In function ‘int main(int, const char**)’:
test_debugger.cpp:2:28: error: non-constant condition for static assertion
 #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
                            ^
test_debugger.cpp:21:5: note: in expansion of macro ‘STATIC_ASSERT’
     STATIC_ASSERT( startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 17 );
     ^~~~~~~~~~~~~
test_debugger.cpp:21:5:   in constexpr expansion of ‘startfindlastslash<30>("cppdebugger/test_debugger.cpp")’
test_debugger.cpp:2:28: error: constexpr call flows off the end of the function
 #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
                            ^
test_debugger.cpp:21:5: note: in expansion of macro ‘STATIC_ASSERT’
     STATIC_ASSERT( startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 17 );

Aucun commentaire:

Enregistrer un commentaire