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

You*_*008 2 c++ string string-comparison string-view

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

但是我想能够比较strings,string_views以及const char*相互之间,提供最大的便利和效率.

所以我在想:如果我制作模板,std::stringbegin/ end,std::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); }
}
Run Code Online (Sandbox Code Playgroud)

这样我就可以比较一切了

std::lexicographical_compare(std::begin(a), std::end(a), std::begin(b), std::end(b), icomp );
Run Code Online (Sandbox Code Playgroud)

如果没有,我怎么能解决我的问题?

Cal*_*eth 7

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

如果C++程序将声明或定义添加到命名空间std或命名空间中的命名空间std ,则除非另有说明,否则C++程序的行为是未定义的.std只有当声明取决于用户定义的类型并且专业化符合原始模板的标准库要求且未明确禁止时,程序才可以将任何标准库模板的模板特化添加到命名空间

[namespace.std/1]

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

const char * begin(const char* str) { return str; }
const char * end(const char* str) { return str + strlen(str); }
Run Code Online (Sandbox Code Playgroud)

并使用不合格的电话

std::lexicographical_compare(begin(a), end(a), begin(b), end(b), icomp );
Run Code Online (Sandbox Code Playgroud)

此外,在C++ 20中,它将更具限制性,仅允许程序定义类型的类模板特化

除非另有说明,否则如果C++程序向命名空间std或命名空间中的命名空间添加声明或定义,则其行为是未定义的std.

除非明确禁止,否则程序可以将任何标准库类模板的模板特化添加到命名空间, std前提是:(a)添加的声明取决于至少一个程序定义的类型;(b)专业化符合原始标准库的要求模板.

[namespace.std]

  • `std :: begin`也不是类模板.请注意,C++ 20将发生重大变化,其中不再允许功能特化:/sf/ask/3693240631/换程序定义的类型-NO-LO/52760860#52760860 (2认同)