操作符重载是否可以在没有引用的情

fre*_*low 6 c++ history language-design reference operator-overloading

根据Bjarne Stroustrup的说法,引用了C++以支持运算符重载:

引用的引用主要是为了支持运算符重载.

C按值传递每个函数参数,并且按值传递对象的效率低或不合适,用户可以传递指针.在使用运算符重载的情况下,此策略不起作用.在这种情况下,符号方便是必不可少的,因为如果对象很大,则不能期望用户插入地址运算符.例如:

a = b - c;
Run Code Online (Sandbox Code Playgroud)

是可接受的(即常规的)符号,但是

a = &b - &c;
Run Code Online (Sandbox Code Playgroud)

不是.无论如何,&b - &c在C中已经有了意义,我不想改变它.

在语言中使用指针和引用是C++新手混淆的常见原因.

Bjarne不能通过引入一种特殊的语言规则来解决这个问题,如果存在需要这样的指针的用户定义的运算符函数,它允许对象参数衰减成指针吗?

减法的声明和用法将如下所示:

Foo operator-(const Foo* x, const Foo* y);
a = b - c;
Run Code Online (Sandbox Code Playgroud)

有没有提出/考虑过这样的解决方案?它有任何严重的缺点吗?

是的我知道,由于它们的限制,引用提供了其他优点,但这不是重点.

有趣的是,带有类的C的赋值运算符似乎完全相同:

通过声明一个名为的成员函数来更改类[...]对象的赋值含义operator=.例如:

class x {
public:
    int a;
    class y * p;
    void operator = (class x *);
};
Run Code Online (Sandbox Code Playgroud)

sbi*_*sbi 7

IME,自动转换是C++的祸根.让我们写一些感谢的电子邮件给Bjarne Stroustrup,因为它没有添加从对象到指针的广泛自动转换.

如果你寻找一个技术原因:在C++中,指针的减法,甚至指向用户定义类型的指针,已经很好地定义了.此外,这会导致每个副本获取对象的重载版操作符的含糊不清.

  • @Fred:但这种歧义只存在于两个用户定义的函数之间.但是指针的'operator -`已经存在,所以那里的模糊性是不可避免的. (2认同)
  • @FredOverflow:哇,所以你说"如果我用一个除指针之外的类型调用函数,那么它们将转换为指针,并且将调用带有指针的用户定义函数.但是如果我用指针调用,带有指针的内置函数将被称为".那......是......**邪恶** (2认同)

jal*_*alf 5

我不明白这是如何解决这个问题的:operator-调用指针已经有了意义.

你要定义一个operator-for Foo*参数,但那已经存在了.

然后你需要一些人为的语义,"当用指针显式调用时,调用指针算术运算符.当用对象左值调用时,它们会衰减为指针,然后调用重载版本".说实话,这似乎更加人为,而且不仅仅是添加引用.

然后在里面operator-,我把参数作为指针,然后我最好确保取消引用那些,如果我需要从那里调用另一个(或相同的)运算符.否则我不小心最终会执行指针算术.

您提出的隐式转换与自己进行转换的语义不同.那是:

Foo foo;
bar(foo); 
Run Code Online (Sandbox Code Playgroud)

执行从Footo 的隐式转换Foo*,然后调用带有签名的函数void bar(Foo*).

但是这段代码会做一些完全不同的事情:

Foo foo;
bar(&foo);
Run Code Online (Sandbox Code Playgroud)

这将转换为一个Foo*,并且它还将要求与签名的功能void bar(Foo*),但它可能会是一个不同的功能.(operator-例如,一个是用户重载的运算符,另一个是标准指针算术运算符.

然后考虑模板代码.通常,隐式转换会使模板非常痛苦,因为传入的类型可能不是您要操作的类型.

当然,还有更多的实际问题:

引用启用指针无法实现的优化.(编译器可以假设它们永远不会为空,并且可能更好地进行别名分析)

而且,如果找不到匹配,代码将无声地失败operator-.而是告诉我的,编译器会隐式地开始做指针算术.不是一个交易破坏者,但我真的更喜欢在可能的情况下及早发现错误.

C++的目标之一是使其具有通用性:避免使用"魔术"类型或功能.在现实世界的C++中,运算符只是具有不同语法的函数.有了这个规则,它们也会有不同的语义.(如果使用函数语法调用运算符怎么operator+(a, b)办?