Providing const- and non-const overloads of a strstr() implementation
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.