In a question about reimplementing strstr()
, I posted an answer. I pointed out a need for const- and non-const versions of the function, and provided Implementation A below, which received criticism about the ugliness of the const_cast
. Therefore, I've written two more implementations (B and C).
Implementation A: const version that chains to a non-const version
char *strstr(char *input, const char *find) {
do {
const char *p, *q;
for (p = input, q = find; *q != '\0' && *p == *q; p++, q++) {
}
if (*q == '\0') {
return input;
}
} while (*(input++) != '\0');
return NULL;
}
const char *strstr(const char *input, const char *find) {
return strstr(const_cast<char *>(input), find);
}
Implementation B: template
template <typename T>
T *strstr(T *input, const T *find) {
do {
const T *p, *q;
for (p = input, q = find; *q != '\0' && *p == *q; p++, q++) {
}
if (*q == '\0') {
return input;
}
} while (*(input++) != '\0');
return NULL;
}
Implementation C: template with char_traits
template <typename T>
struct char_traits {
typedef T type;
typedef const T const_type;
};
template <typename T>
static typename char_traits<T>::type *strstr(
typename char_traits<T>::type *input,
typename char_traits<T>::const_type *find) {
do {
typename char_traits<T>::const_type *p, *q;
for (p = input, q = find; *q != '\0' && *p == *q; p++, q++) {
}
if (*q == '\0') {
return input;
}
} while (*(input++) != '\0');
return NULL;
}
// Explicit instantiation doesn't help with overloading?
// http://stackoverflow.com/a/8061522/1157100
//
// template char *strstr<char>(char *input, const char *find);
// template char *strstr<const char>(char *input, const char *find);
// So it seems that chaining is still necessary?
const char *strstr(const char *input, const char *find) {
return strstr<const char>(input, find);
}
char *strstr(char *input, const char *find) {
return strstr<char>(input, find);
}
I suspect that I may have done something stupid with (C), since I'm still chaining the calls. Is there a way to provide an overloaded strstr()
just using template instantiation?
Of the three approaches, which is best, and why?