为什么C++运算符重载要求“至少有一个类类型的参数”?

2024-01-27

《C++ Primer 第 5 版》第 14.1 章写道,

运算符函数必须是类的成员,或者至少具有一个类类型的参数。

例如,string("hello")+"world"编译"hello"+"world"没有。当我想要超载时+在两个 C 弦上。

std::string operator+ (const char* s1, const char* s2)

我收到以下错误。

错误:‘std::string operator+(const char*, const char*)’必须具有类或枚举类型的参数

我有两个问题。

  1. 此限制是语言规范的一部分吗?如果是的话,为什么 C++ 设计者想要这样做?

  2. std::string有类似的构造函数string (const char* s);,这意味着编译器可以从char* to string。当我们打电话时"hello"+"world", 为什么编译器不转换两者char*“到两个字符串?毕竟,两个 std::string 上有一个重载“+”。string operator+ (const string& lhs, const string& rhs);


  1. 此限制是语言规范的一部分吗?

是的。为什么?好吧,主要原因可能是因为重新定义标准类型的常用运算符被认为是令人困惑的。想象一下超载operator+(int,int) or operator+(int,char*)。这将改变现有代码的含义!

您可能会争辩说,标准类型之间存在未定义的运算符,因此您可以安全地覆盖它们,例如operator*(char*,int),但这通常被认为是毫无用处的。

此外,运算符重载必须是全局的(或者位于其某些成员的命名空间中(参数相关查找),但对于标准类型,没有命名空间可供依赖),因此想要覆盖它们的库之间的互操作性将是一个问题恶梦。

  1. "hello" + "world":为什么编译器不将两个 char* " 转换为两个字符串?

嗯,一方面,std::operator+(const std::string&, const std::string&) is in namespace std;所以默认是找不到的。

您可以尝试显式调用运算符:std::operator+("hello", "world"),但可惜的是,有这么多operator+()重载,其中许多是模板,调用是不明确的。

因此,考虑到所有这些,我认为合理的要求是至少其中一个运算符是用户定义的类型。想一想:全局和命名空间问题解决了,ADL就可以用了(其实就是为了这个用途而发明的),不可能重新定义一个已有含义的操作符(除了operator,() and operator&(),我想,但是谁想覆盖这些......)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么C++运算符重载要求“至少有一个类类型的参数”? 的相关文章

随机推荐