为 const char* 定义 std::begin 是否合法?

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

我有一个不区分大小写的字符串比较函数,它使用 std::lexicographical_compare 和自定义比较器。

但是我希望能够相互比较 stringsstring_viewsconst char*,以获得最大的便利性和效率。

所以我在想:如果我做一个模板呢,std::stringbegin/endstd::string_viewbegin/end, ... 但 const char* 没有,甚至以非成员函数的形式也没有。

所以可以像这样定义自己的 begin/end 重载

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

这样我就可以通过

比较所有的东西
std::lexicographical_compare(std::begin(a), std::end(a), std::begin(b), std::end(b), icomp );

?

如果没有,我还能如何解决我的问题?

不,这不合法,因为const char *不是用户定义的类型。

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]

您可以改为在其他命名空间中声明它们,例如 ::

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

并将它们用于不合格的调用

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

此外,在 C++20 中,它将更加严格,只允许 class 程序定义类型的模板特化

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]