当这样的重载不存在时,是否允许重载运算符,例如operator+
,以获得标准库类型和内置类型的组合?
例如,在默认命名空间或用户定义的命名空间中实现以下运算符是否合法:
std::string operator+(const std::string& s, int right) { ... }
我知道在 std::
命名空间中实现的内容存在各种限制,但我不清楚是否有针对上述内容的规则(是否是个好主意)当然是完全不同的事情!)。
答案 0 :(得分:3)
在operator+
和std::string
之间重载int
是完全可以的。标准对此的唯一限制是(https://timsong-cpp.github.io/cppwp/n3337/over.oper#6):
运算符函数应该是非静态成员函数或者是非成员函数,并且至少有一个参数,其类型是类,对类的引用,枚举或对枚举的引用。
即使是标准库中的类型,也无法在命名空间中定义它们。
答案 1 :(得分:2)
例如,在默认命名空间或用户定义的命名空间中实现以下运算符是否合法:
std::string operator+(const std::string& s, int right) { ... }
是的,这样做是完全合法的。唯一的限制是将名称添加到namespace std
或专门的成员函数功能模板或类模板,或者为std
中的类模板添加演绎指南。
没有什么能阻止你写下这样的东西:
namespace N {
std::string operator+(std::string s, int ) { return s; }
}
根据标准,这是一个结构良好的计划。但请注意,根据定义,您的运算符中不会包含任何程序定义的类型,ADL永远不会找到它们。由于它们是ADL常见的运算符,因此这本身可能是避免这种模式的原因:
namespace U {
auto foo() {
return "hello"s + 1; // error: name lookup doesn't find our operator
}
auto bar() {
using namespace N;
return "hello"s + 1; // ok: for some definition of ok
}
}
答案 2 :(得分:2)
写这个是合法的。但它不一定能做你想做的事。
如果您的目标是制作some_string + 4
合法的C ++代码,那么它的合法性将取决于该表达式的确切位置。运算符重载将使用ADL查找运算符[over.match.oper] /3.2:
非成员候选集是根据非限定函数调用(6.4.2)中通常的名称查找规则,在表达式上下文中对operator @进行非限定查找的结果,除了忽略所有成员函数。但是,如果没有操作数具有类类型,则只有那些非成员 查找集中具有第一个参数类型为T1或“引用到cv T1”的函数,当T1是枚举类型时,或者(如果有右操作数)第二个参数类型为T2或“引用到cv T2” ,当T2是枚举类型时,是候选函数。
但由于您的operator+
不与任一参数在同一名称空间中,因此ADL查找将失败。非会员候选人名单不会自动包含全球职能,因此没有机会找到合适的operator+
。
因此,如果不打开命名空间,就无法有效地重载此类运算符。当然禁止std
。