所有 C++ 运算符都会返回一些东西吗?

use*_*761 83 c++ operators

我使用过的所有 C++ 运算符都会返回一些东西,例如+运算符返回加法的结果。

是否所有 C++ 运算符都返回某些内容,或者是否有一些 C++ 运算符不返回任何内容?

Adr*_*ica 113

不,并不是所有的操作符都会返回一些东西。

虽然他们也有可能不是正好你在想什么,注意deletedelete[]C ++“关键字”实际上是运营商; 并且它们被定义为具有void返回类型 - 这意味着它们的评估结果为零(这不是“某物”)。

cppreference

void operator delete  ( void* ptr ) noexcept;
void operator delete[]( void* ptr ) noexcept;
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢你的回答,它让我以不同的方式思考这个问题。`delete`、`delete[]`、`throw`、`(void)x;` 强制转换、`,` 运算符的左侧、`,` 运算符的右侧,生成一个 `void`、一个 `?:`对其中一个手臂使用 `throw` 的三元组,dfri 的 `operator void()` (将由用户定义)、Mornりネroku 的 `void operator()()` (将由用户定义)。 (13认同)
  • 同样令人困惑的是,“删除”运算符销毁对象,然后调用“删除运算符”。因此,“删除”运算符和“删除运算符”是不同的东西:( /sf/answers/624325971/ (10认同)
  • 不知道为什么在谈论删除运算符时引用删除函数。但是无所谓。 (7认同)
  • @MooingDuck 删除 *表达式* 销毁对象,然后调用“operator delete”。 (4认同)

for*_*818 82

自定义类型的运算符可以被重载来做最奇怪的事情。

例如 + 运算符返回加法的结果。

不必要:

#include <iostream>
struct foo {
    int value = 0;
    void operator+(int x) {
        value += x;
    }
};

int main () {
    foo f;
    f + 3;
}
Run Code Online (Sandbox Code Playgroud)

此处operator+将左侧添加到value成员中,其返回类型为 void。这是一个虚构的示例,但一般来说,不从自定义运算符返回某些内容并不罕见。

我知道,唯一可以重载并且需要返回某些内容的运算符是operator->. 它必须返回一个原始指针或一个带有operator->.

  • @idclev463035818:也许更有用的例子是表达式模板。例如,您可以创建一个矩阵库,其中“operator*(Matrix const&amp; left, Matrix const&amp; right)”返回的不是“Matrix”,而是“MatrixMul”,这样如果将其输入“operator+(Matrix const&amp; left, MatrixMul” const&amp; right)` 该运算可以是融合乘加,比先乘后加更有效。 (9认同)
  • @braccor23 `operator-&gt;` 有点特殊,需要返回一个指针或一个具有 `operator-&gt;` 的对象,不确定是否还有其他异常 (5认同)

Sto*_*ica 34

挑剔,运营商不返回任何东西。它们只是我们用来在语言中创建表达式的词汇元素。现在,表达式具有类型并且可以评估为值,我认为这就是您所说的运算符“返回事物”的意思。

而且,嗯,是的。有带有类型的 C++ 表达式void(因此不计算任何值)。有些是显而易见的,有些则不那么明显。一个很好的例子是

throw std::runtime_error()
Run Code Online (Sandbox Code Playgroud)

throw是 C++ 语法下的表达式。您可以在其他表达式中使用它,例如在条件表达式中

return goodStatus() ? getValue() : throw std::runtime_error();
Run Code Online (Sandbox Code Playgroud)

而 throw 表达式的类型是void。显然,由于这只会导致执行快速转到其他地方,因此该表达式没有任何价值。


Bat*_*eba 21

内置的 C++ 运算符都不返回任何内容。重载的 C++ 运算符返回一些东西,因为运算符符号是函数调用的语法糖。

相反,运营商都评估某事。那个东西有一个明确定义的value和一个type。甚至函数调用运算符void operator()(/*params*/)也是一种void类型。

例如,+'a'是在您的平台上int具有'a'编码值的类型。

如果您的问题是“C++ 运算符可以有void返回类型吗?” 那么答案肯定是肯定的。

  • @idclev463035818:我对“返回”一词有疑问。C++ 中唯一返回某些内容的是函数。表达式*评估*某事物。 (14认同)
  • 类类型的运算符是返回某些内容的方法 (7认同)
  • 这是很重要的一点。草率的术语会导致混乱。+1。 (4认同)
  • @supercat——你的评论诽谤了一群勤奋的人,包括我。我们这些编写标准的人**从未**期望编译器编写者通过轮询当前或过去的其他编译器来填写详细信息。该标准的目标过去和现在都是明确定义 C++ 编程语言的语法和语义。是的,结果并不完美;最新标准中解决了许多早期版本中未解决的问题。这来自于经验,认识到当时根本没有见过的并发症。 (3认同)
  • @Peter-ReinstateMonica — 这是一个更强的版本。表达式“I++”不返回值。如果“i”的类型是用户定义的类型,则该表达式将实现为“operator++”,它是一个返回值的函数。你称之为“语法糖”;我称之为具有重要后果的区别。 (3认同)
  • @PeteBecker 恕我直言;如果实现包含带有值的 return 语句,“C++ 运算符都不返回某些内容”似乎是不合逻辑的。我一直认为运算符只是函数的语法糖,其中许多函数在该术语的所有合理使用中肯定会“返回某些内容”。不是这样吗?(当然,函数也“评估某物”;“返回”是被调用者的角度,“评估”是调用者的角度。)我看不到你所看到的重点。 (2认同)

眠りネ*_*ネロク 13

您实际上可以定义一个函数调用运算符来不返回任何内容。例如:

struct Task {
   void operator()() const;
};
Run Code Online (Sandbox Code Playgroud)

  • 您可以定义几乎任何运算符不返回任何内容(并面对必须维护该代码的愤怒暴民的愤怒) (17认同)
  • @Yksisarvinen 但至少这个可能有用。 (7认同)

dfr*_*fri 11

operator void():用户定义的转换函数void

您可以定义特殊的operator void()转换函数,编译器甚至会警告您永远不会使用Ttovoid转换函数:

#include <iostream>

struct Foo {
    operator void() { std::cout << "Foo::operator void()!"; }
    // warning: conversion function converting 'Foo' to 
    //          'void' will never be used
};
    
int main() {
    Foo f;
    (void)f;            // nothing
    f.operator void();  // Foo::operator void()!
}
Run Code Online (Sandbox Code Playgroud)

[class.conv.fct]/1管辖

[...]从未使用转换函数将(可能是 cv 限定的)对象转换为(可能是 cv 限定的)相同对象类型(或对它的引用),或(可能是 cv 限定的)基类该类型的(或对它的引用),或(可能是 cv 限定的) void117

( 117 ) 出于重载解析([over.best.ics]、[over.ics.ref])以及初始化([dcl.init])和显式强制转换的目的,这些转换被视为标准转换。转换为void不调用任何转换函数([expr.static.cast])。即使从未直接调用来执行转换,也可以声明此类转换函数,并且可以通过调用基类中的虚拟转换函数来潜在地访问它们。

然而,如上所示,您仍然可以使用显式.operator void()语法调用它。


小智 5

语言定义(内置)的运算符是用于执行不同类型计算的标记:

  • 算术 (+,-,*,/)
  • 递增/递减 (++,--)
  • 赋值 (=,+=,-=,*=,/=,%=,>>=,<<=,&=,^=,|=)
  • 逻辑 (!,&&,||)
  • 关系 (==,!=,>,<,>=,<=)
  • 有条件的?
  • 逗号

等等。该列表可能非常广泛。

在像这样这样的语言引用中,这些不一定被引用为返回某些东西,只是执行算术或逻辑运算,通过比较可以修改变量等。

由于此操作会产生一些值,因此可以将其解释为运算符“返回”,但它与函数返回值不同。

另一方面,重载运算符可以定义为某种类型的返回值,即使可以是 void,因此,并非所有运算符都在 C++ 中返回某个值。