运算符重载在没有引用的情况下是否可以工作? 根据Bjarne Stroustrup,引用引用到C++中支持运算符重载:

运算符重载在没有引用的情况下是否可以工作? 根据Bjarne Stroustrup,引用引用到C++中支持运算符重载:,c++,operator-overloading,reference,history,language-design,C++,Operator Overloading,Reference,History,Language Design,引入引用主要是为了支持运算符重载 C按值传递每个函数参数,如果按值传递对象效率低或不合适,用户可以传递指针。在使用运算符重载的情况下,此策略不起作用。在这种情况下,符号方便是必不可少的,因为如果对象较大,则不能期望用户插入运算符的地址。例如: a = b - c; class x { public: int a; class y * p; void operator = (class x *); }; 是可接受的(即常规)符号,但 a = &b - &

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

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

a = b - c;
class x {
public:
    int a;
    class y * p;
    void operator = (class x *);
};
是可接受的(即常规)符号,但

a = &b - &c;
事实并非如此。无论如何,
&b-&c
在c中已经有了意义,我不想改变它

语言中的指针和引用都是C++初学者的一个经常混淆的来源。 Bjarne难道不能通过引入一种特殊的语言规则来解决这个问题吗?如果存在一个接受此类指针的用户定义运算符函数,该规则允许对象参数衰减为指针

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

Foo operator-(const Foo* x, const Foo* y);
a = b - c;
是否曾提出/考虑过这样的解决方案?这会有什么严重的负面影响吗

是的,我知道,由于他们的限制,推荐信提供了其他优势,但这不是重点

有趣的是,C类的赋值运算符的工作原理似乎与此完全相同:

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

a = b - c;
class x {
public:
    int a;
    class y * p;
    void operator = (class x *);
};
。让我们写一封感谢的电子邮件给比亚恩·斯特劳斯特鲁普,感谢他没有添加从对象到指针的全面自动转换


如果你寻找一个技术原因:在C++中,指针的减法,甚至指针到用户定义类型的定义都已经被定义。此外,这将导致每个副本都接受对象的重载版本的运算符出现歧义

如果您接受使用指针(隐式或显式)会引入非常混乱的语义(我是在指针上操作还是在指针对象上操作?),那么没有只留下按值调用的引用。(除了你的代码> foc= & b& &;< /c>示例,考虑你想编写一个确实使用指针作为参数之一的运算符)

。 我不认为在调用站点没有
&
的指针是有用的,当然也不比引用更好。如果将其作为
操作符
s的一个特殊功能,并且只使用操作符,那么这将使行为很好地进入“神秘”的特例领域。如果你想通过让它成为一个通用的特性来减少它的“特殊情况”方面,那么我认为它在目前的引用调用中是没有帮助或有用的

例如,如果我想编写一个运算符,它接受一个
Foo
和一个
void*
,我可以编写:

Foo operator+(const Foo& f, void *ptr);
根据您提议的规则,将成为:
Foo operator+(Foo*f,void*ptr)。我所看到的问题是,即使我希望
ptr
通过“隐式
&
规则”显式地成为指针,它也会接受任何东西,而且似乎没有办法禁止自动转换。So
double-d;福福;f=f+d将与之匹配,就像
inti;福福;f=f+i,可能有两种不同的方式


按值调用可能对“简单”类型有效且有意义,并且在您确实不想获取每个操作数的副本的情况下,可以使用智能指针。总的来说,与基于引用的方法相比,被迫复制所有内容的想法似乎非常不干净

C++的目标是强类型,因此,为了与这一理念保持一致,一个对象不是指向该对象的指针是有道理的,我完全同意sbi的观点,即不进行自动转换是多么好(我想到的是多贡献者项目)

为了更具体地解决你的问题,学习C++的人一开始可能会被引用和指针混淆,但是我不确定它是否能为他们提供任何自动转换。 例如:

Foo ** operator+(Foo **lhs, Foo **rhs)
{...}

Foo *varFoo1,*varFoo2;
varFoo1 + &varFoo2;
在假设的隐式对象指向指针之后,varFoo1是否应被接受为预期为Foo**的方法的参数?因为该方法需要指向Foo*的指针,而varFoo1*是-a*Foo*

用作参数的引用的另一个优点:

常量引用可以接收一个右值作为参数(例如经典的字符串文字),而指针不能。

我不知道这是如何解决问题的:
操作符-
在指针上调用已经有了意义

您应该为
Foo*
参数定义一个
操作符-
,但它已经存在

然后,您需要一些精心设计的语义,“当使用指针显式调用时,将调用指针算术运算符。当使用对象左值调用时,它们将衰减为指针,然后调用重载版本”。老实说,这似乎比仅仅添加引用更为做作,更不直观

然后在
操作符-
中,我将参数作为指针,如果需要从那里调用另一个(或同一个)操作符,我最好确保取消引用这些参数。否则我会意外地执行指针算术

您提出的隐式转换与您自己进行转换的语义不同。即:

Foo foo;
bar(foo); 
执行从
Foo
Foo*
的隐式转换,然后调用带有签名
无效条(Foo*)
的函数

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

Foo foo;
bar(&foo);
<