Providing const- and non-const overloads of a strstr() implementation 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' &amp;&amp; *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&lt;char *&gt;(input), find);
}


Implementation B: template

template &lt;typename T&gt;
T *strstr(T *input, const T *find) {
    do {
        const T *p, *q;
        for (p = input, q = find; *q != '\0' &amp;&amp; *p == *q; p++, q++) {
        }
        if (*q == '\0') {
            return input;
        }
    } while (*(input++) != '\0');
    return NULL;
}


Implementation C: template with char_traits

template &lt;typename T&gt;
struct char_traits {
    typedef T type;
    typedef const T const_type;
};

template &lt;typename T&gt;
static typename char_traits&lt;T&gt;::type *strstr(
        typename char_traits&lt;T&gt;::type *input,
        typename char_traits&lt;T&gt;::const_type *find) {
    do {
        typename char_traits&lt;T&gt;::const_type *p, *q;
        for (p = input, q = find; *q != '\0' &amp;&amp; *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&lt;char&gt;(char *input, const char *find);
// template char *strstr&lt;const char&gt;(char *input, const char *find);

// So it seems that chaining is still necessary?
const char *strstr(const char *input, const char *find) {
    return strstr&lt;const char&gt;(input, find);
}

char *strstr(char *input, const char *find) {
    return strstr&lt;char&gt;(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?
I don't like casting away const on a const object.
This opens you up to the possibility of maintenance errors.

const char *strstr(const char *input, const char *find)
{
    return strstr(const_cast&lt;char *&gt;(input), find);
}


Here you are assuming that the other version of strstr() will not attempt to mangle the input. This may be fair to assume in the original version, but what if somebody makes a mistake while updating to use a better algorithm. The compiler will not detect the problem and you are left with UB.

I would just do it the other way around:

char const* strstr(char const* input, char const* find)
{
   do {
        char const* p;
        char const* q;
        for (p = input, q = find; *q != '\0' &amp;&amp; *p == *q; p++, q++) {
        }
        if (*q == '\0') {
            return input;
        }
    } while (*(input++) != '\0');
    return NULL;
}

char* strstr(char* input, char const* find)
{
    return const_cast&lt;char*&gt;(strstr(const_cast&lt;char const*&gt;(input), find));
}


OK. So we need to add another cast. But in this version we protect ourselves from errors. If there is an error in the algorithm (were input is modified) then the compiler will now be able to detect it.

The const_cast&lt;> to remove const(ness) is in a safe place returning the pointer to its original state (after there is const_cast&lt;> to add const (needed so we can differentiate the two functions).

Personally I would take it a step further (so we can remove one of the const_casts). By making the strstr() just wrapper functions around the function that does the work.

char const* strstrDo(char const* input, char const* find)
{
   do {
        char const* p;
        char const* q;
        for (p = input, q = find; *q != '\0' &amp;&amp; *p == *q; p++, q++) {
        }
        if (*q == '\0') {
            return input;
        }
    } while (*(input++) != '\0');
    return NULL;
}

// Interface for backwards compatibility with old C code
// that does not handle const correctness well.
char* strstr(char* input, char const* find)
{
    // It is safe to cast away the const(ness) here.
    // The result of `strstrDo()` is a location inside
    // `input` (which we already know is non const) or
    // it is NULL (where the type is less relevant).

    return const_cast&lt;char*&gt;(strstrDo(input, find));
}

// Correct interface.
char const* strstr(char const* input, char const* find)
{
   return strstrDo(input, find);
}


Don't like Implementation B: template because it has the same problems in that errors (in modification input are not detected by the compiler (potentially)).

Same for Implementation C: template with char_traits. But that goes way over the top. I don't actually see the need for the traits on such a simple function.