Is it legit to define std::begin for const char*?

Viewed 1261

I have a function for case insensitive comparison of strings which uses std::lexicographical_compare with custom comparator.

However i would like to be able to compare strings, string_views and const char* between each other, for maximum convenience and efficiency.

So i was thinking: What if i make a template, std::string has begin/end, std::string_view has begin/end, ... but const char* doesn't, not even in a form of non-member function.

So it is ok to define own begin/end overloads like this

namespace std {
    const char * begin(const char* str) { return str; }
    const char * end(const char* str) { return str + strlen(str); }
}

so that then i can compare everything with everything by

std::lexicographical_compare(std::begin(a), std::end(a), std::begin(b), std::end(b), icomp );

?

If not, how else could i solve my problem?

1 Answers

No, this is not legal, because const char * is not a user-defined type.

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited

[namespace.std/1]

You can instead declare those in some other namespace, such as ::

const char * begin(const char* str) { return str; }
const char * end(const char* str) { return str + strlen(str); }

And use them with unqualified calls

std::lexicographical_compare(begin(a), end(a), begin(b), end(b), icomp );

Additionally, in C++20, it will be even more restrictive, permitting only class templates specialisations for program-defined types

Unless otherwise specified, the behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std.

Unless explicitly prohibited, a program may add a template specialization for any standard library class template to namespace std provided that (a) the added declaration depends on at least one program-defined type and (b) the specialization meets the standard library requirements for the original template.

[namespace.std]

Related