The problem is in the const
ness. If you look closely const T* my_Tptr
means my_Tptr is a pointer to const T. But const char** my_Tptr
means Tptr is a pointer to pointer to const char. So the type moves from pointer to const T to pointer to pointer to const T. If you make it char* const* my_Tptr*
then it will work, since then the type will be pointer to const char pointer. The specialization is pointer to const T*->pointer to const char*
Using const char** with Template Specialization
-
19-07-2023 - |
質問
I am trying to write a template specialization for a function that returns the maximum value of an array of numeric values (general version) or the longest c-string of an array of c-strings (specialization). If I do not use const-ness, my function prototypes look like this
template <typename T>
T maxn(T* my_Tptr, unsigned int n);
template <>
char* maxn <char*> (char** my_cstrings, unsigned int n);
and my code compiles.
However, if I try to use const-ness, my function prototypes look like this,
template <typename T>
T maxn(const T* my_Tptr, unsigned int n);
template <>
char* maxn <char*> (const char** my_cstrings, unsigned int n);
my code does not compile, and the compiler (gcc) prints this error:
error: template-id 'maxn' for 'char* maxn(const char**, unsigned int)' does not match any template declaration.
Where am I going wrong?
解決
他のヒント
Not sure what is the whole logic behind it but if you change your template definition to say that you are expecting pointers that will help:
template <typename T>
T* maxn(const T** my_Tptr, unsigned int n);
template <>
char* maxn(const char** my_cstrings, unsigned int n);
You might provide several overloads for the char-case to resolve the issue:
#include <iostream>
#include <stdexcept>
template <typename T>
T maxn(const T* const data, unsigned int n) {
throw std::logic_error("Failure");
}
const char* maxn(const char * const * data, unsigned int n) {
return "Success";
}
inline const char* maxn(const char** data, unsigned int n) {
return maxn(static_cast<const char * const *>(data), n);
}
inline const char* maxn(char* const * data, unsigned int n) {
return maxn(static_cast<const char * const *>(data), n);
}
inline const char* maxn(char** data, unsigned int n) {
return maxn(static_cast<const char * const *>(data), n);
}
int main() {
const char* a[] = { "A", "B", "C" };
std::cout << maxn((const char * const *)a, 3) << '\n';
std::cout << maxn((const char **)a, 3) << '\n';
std::cout << maxn((char * const *)a, 3) << '\n';
std::cout << maxn((char**)a, 3) << '\n';
}
This compiles fine:
template <>
char* maxn(char* const* my_cstrings, unsigned int n);
It accepts a pointer to a const char pointer like specified in the base template.