强制某些运营商成为成员的理由

Rationale of enforcing some operators to be members

提问人:Armen Tsirunyan 提问时间:10/15/2010 最后编辑:CommunityArmen Tsirunyan 更新时间:3/4/2016 访问量:1802

问:

C++ 中有 4 个运算符可以重载,但不能作为独立(又名非成员、独立)函数重载。这些运算符是:

  • operator =
  • operator ()
  • operator ->
  • operator []

这个线程很好地解释了禁止成为非成员函数背后的基本原理。对其他三个有什么想法吗?operator =

C 运算符重载 C++-FAQ

评论

3赞 James McNellis 10/15/2010
我很确定可以作为非成员函数实现。->*
2赞 GManNickG 10/15/2010
@James:你说得对。@Armen:可能只是目光短浅。
0赞 Armen Tsirunyan 10/15/2010
@James。简而言之,C++一书说了不然......
1赞 Andrey 10/15/2010
@Armen Tsirunyan,您应该检查标准
2赞 Armen Tsirunyan 10/15/2010
@Andrey:对于所有其他运营商来说,几乎都可以这样说,所以我认为这不是答案。

答:

21赞 Cheers and hth. - Alf 10/15/2010 #1

原始帖子中提到的四个运算符 , , 和 确实必须实现为非静态成员函数(分别由 C++98 §13.5.3/1、§13.5.4/1、§13.5.5/1 和 §13.5.6/1)。=()->[]

Bjarne Stroustrup 的基本原理是,正如我从之前关于这个主题的辩论中回想起的那样,在语言中保留一些理智,即至少有一些东西你可以依赖,无论其他人通过为现有类定义非成员运算符而搞砸了多少。

我不确定我是否完全同意限制是否真的有助于这一点,但是。

编辑:我就此咨询了Bjarne Stroustrup(他总是很有帮助),但似乎规则的明显不一致只不过是冻结历史事故的案例。他指出,“现在看起来比那时更糟,因为自从制定重载规则以来,我们的左值和引用规则已经发生了变化。几年前,我试图再次研究这个问题,但在提出完整的提案之前已经没有时间了。

干杯 & hth.,

PS:“C++的设计与演变”这本书非常适合这类问题,但不幸的是我没有。

评论

0赞 Armen Tsirunyan 10/15/2010
在这种情况下,-> 和 ->* 之间的主要区别究竟是什么?为什么一个人不能成为非会员,而另一个人可以?顺便说一句,我对“没有认真的理由”之类的答案持开放态度。这是不合逻辑的,但事实就是如此“,尽管如果是这样的话,我肯定会感到失望
0赞 Cheers and hth. - Alf 10/15/2010
@Armen:问得好。我不知道。也许这是在“设计与进化”中解释的,如果是这样,也许有这本书的人会插话。我检查了旧的 ARM,它似乎没有讨论它。
0赞 AnT stands with Russia 8/16/2011
D&E确实提出了基本原理,并且至今仍然有效。我不知道为什么这个限制也被强加在 、 和 上。=()[]->
0赞 curiousguy 12/12/2011
"至少有一些你可以依赖的东西,无论别人搞砸了多少“ 很有趣,在一种可能重载的语言中,但随后它们失去了通常的语义,并且无法重新创建特殊语义。&&||,
0赞 Puppy 3/10/2012
@curiousguy:它确实可以在许多表达式模板系统中重新创建。
2赞 Dingo 10/15/2010 #2

comp.std.c++ 上的这个线程讨论了这个问题。

委员会成员弗朗西斯·格拉斯博罗(Francis Glassborow)表示:

语言设计者不想支持转换和 运算符 = 左侧操作数上的促销,在 () 和 [] 的操作数。

尽量避免以下情况:

class A {};

class B { B(A& a) {} };

int operator()(B const& b) { return 0; }


int main(void)
{
    A a;

    // This works even though A doesn't have a () operator
    // It creates a temporary B and calls operator()(B& b)
    return a();                   
}

评论

3赞 Cheers and hth. - Alf 10/15/2010
Nit:你需要避免试图将临时绑定到对 non-.无论如何,阿门关于这个问题仍然存在。int operator()(B const& b)const->*
2赞 Armen Tsirunyan 10/15/2010
“语言设计者不想支持()左边操作数的转换和推广”。但是,当类声明指向指针函数的转换函数时,它们确实允许这样做......
2赞 GManNickG 10/15/2010
我看不出反对意见的有效性。如果 has 并且 can be explicitly created from an ,为什么要阻止它?Boperator()A
0赞 MSalters 10/15/2010
@GMan:参见Alf P. Steinbach的评论,“保持一些理智”。
1赞 GManNickG 10/15/2010
@MSalters:我不认为这太疯狂了。:)