为什么C ++运算符重载需要“至少具有一个类类型的参数"? [英] why C++ operator overloading requires "having at least one parameter of class type"?

查看:97
本文介绍了为什么C ++运算符重载需要“至少具有一个类类型的参数"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

"C ++入门第五版"的第14.1章读到,

The chapter 14.1 of "C++ primer 5th edition" reads,

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

An operator function must either be a member of a class or have at least one parameter of class type.

例如, string("hello")+"world" 不会编译"hello" +"world" .当我想在两个C字符串上重载 + 时.

For example, string("hello")+"world" compiles "hello"+"world" doesn't. And when I want to overload the + on two C strings.

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

我收到以下错误.

错误:"std :: string运算符+(const char *,const char *)"必须具有class或枚举类型的参数

error: ‘std::string operator+(const char*, const char*)’ must have an argument of class or enumerated type

我有两个问题.

  1. 此限制是否在语言规范中?如果是,为什么C ++设计人员想要这样做?

  1. Is this restriction part of the language specification? If yes, why C++ designers want to do that?

std :: string 具有类似于 string(const char * s); 的构造函数,这意味着编译器可以从进行隐式类类型转换.> char * 转换为 string .当我们调用"hello" +"world" 时,编译器为什么不将两个 char * "s转换为两个字符串?总而言之,两个std :: strings上都有一个重载的"+". string运算符+(const string& lhs,const string& rhs);

std::string has constructor like string (const char* s);, which implies that compiler can do implicit class-type conversion from char* to string. When we call "hello"+"world", why doesn't the compiler convert the two char* "s to two strings? After all, there is a overloading "+" on two std::strings. string operator+ (const string& lhs, const string& rhs);

推荐答案

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

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

Yes, it is. Why? Well, the main reason is probably because redefining the usual operators for standard types is seen as obfuscating. Imagin overloading operator+(int,int) or operator+(int,char*). That would change the meaning of existing code!

您可能会说标准类型之间存在未定义的运算符,因此可以放心地覆盖它们,例如 operator *(char *,int),但这通常被认为是没有用的.

You could argue that there are operators between standard types that are not defined, so you could safely override them, for example operator*(char*,int), but that is usually seen as rather useless.

此外,运算符重载必须是全局的(或在其某些成员的名称空间(依赖于参数的查找)中,但是对于标准类型,没有名称空间可依赖),因此,希望覆盖它们的库之间的互操作性会是一场噩梦.

Moreover, operator overloads must be global, (or be in the namespace of some of its members (argument dependent lookup), but with standard types there are no namespace to depend on), so interoperatibility between libraries that fancy to override them would be a nightmare.

  1. "hello" +"world" :为什么编译器不将两个char *转换为两个字符串?
  1. "hello" + "world": why doesn't the compiler convert the two char* "s to two strings?

好吧, std :: operator +(const std :: string& ;, const std :: string&)位于 namespace std; 中,所以它不会默认情况下会被找到.

Well, for one, std::operator+(const std::string&, const std::string&) is in namespace std; so it will not be found by default.

您可以尝试显式调用运算符: std :: operator +("hello","world"),但是可惜,有很多 operator +()重载,其中有许多模板是通话模棱两可的.

You could try calling the operator explicitly: std::operator+("hello", "world"), but alas, there are so many operator+() overloads, many of them templates, that the call is ambiguous.

因此,考虑到所有这些因素,我认为一个合理的要求是至少一个运算符必须是用户定义的类型.考虑一下:解决了全局和名称空间问题,可以使用ADL(实际上是为此而发明的),并且不可能重新定义具有现有含义的运算符( operator,()除外)我想是 operator&(),但谁想重写这些...).

So, taking all this into account, I think that a reasonable requirement is that at least one of the operators to be of a user-defined type. Think about it: the global and namespace problem is solved, ADL can be used (actually it was invented for this use) and it is impossible to redefine an operator with an existing meaning (except operator,() and operator&(), I think, but who wants to override these...).

这篇关于为什么C ++运算符重载需要“至少具有一个类类型的参数"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆