是否允许过载运算符,例如operator+
,用于组合标准库类型和内置类型,当不存在此类超载时?
例如,在默认名称空间或用户定义的名称空间中实现以下操作员是合法的:
std::string operator+(const std::string& s, int right) { ... }
我知道在std::
名称空间中实施事物有各种限制,但是我尚不清楚是否有任何反对上述规则完全不同的物质!)
例如,在默认名称空间或用户定义的名称空间中实现以下操作员是合法的:
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
}
}
写这篇文章是合法的。但这不一定要做您想要的。
如果您的目标是制作some_string + 4
Legal C 代码,则其合法性将完全取决于该表达式出现的位置。操作员的超载将使用ADL查找操作员[Over.match.oper]/3.2:
根据表达式在表达式的上下文中,根据callive unight的函数调用(6.4.2),在表达式的上下文中,@ operator@的不合格查找的结果(6.4.2)的结果是。。但是,如果没有操作数具有类型,则只有那些非会员 查找集中的函数在T1类型的第一个参数或"引用CV T1",T1是枚举类型时,或(如果有正确的操作数)T2类型的第二个参数或"引用CV T2",当T2是枚举类型时,是候选功能。
但是,由于您的operator+
是不是在同一命名空间中,因此ADL查找将失败。非成员候选人的列表将不会自动包含全局功能,没有机会找到正确的operator+
。
因此,您不能有效地超载这样的操作员而无需打开命名空间。当然,std
禁止哪个。
在std::string
和int
之间过载operator+
是完全可以的。标准位置的唯一限制是(https://timsong-cpp.github.io/cppwp/n33337/over.oper#6):
操作员函数应为非静态成员函数,或者是非会员函数,并且至少具有一个参数,其类型是类,对类,枚举或对枚举的引用。
,即使是标准库中的类型,也没有限制在您的命名空间中定义它们。