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 versionchar *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: templatetemplate <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_traitstemplate <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?
Providing const- and non-const overloads of a strstr() implementation
c++;reinventing the wheel;template meta programming;comparative review;overloading