我使用过的所有 C + + 操作符都返回一些内容,例如 +操作符返回加法的结果。
+
是所有的 C + + 操作符都返回一些东西,还是有一些 C + + 操作符不返回任何东西?
你实际上可以定义一个 函数调用运算符函数调用运算符来不返回任何东西。例如:
struct Task { void operator()() const; };
自定义类型的运算符可能会被重载,以便执行最奇怪的操作。
例如,+ 运算符返回加法的结果。
不一定:
#include <iostream> struct foo { int value = 0; void operator+(int x) { value += x; } }; int main () { foo f; f + 3; }
这里,operator+将左侧添加到 value成员,其返回类型为 void。这是一个虚构的示例,但是一般来说,不从自定义运算符返回某些内容并不罕见。
operator+
value
据我所知,唯一可以重载并且需要返回一些内容的操作符是 operator->。它必须返回原始指针或具有 operator->的对象。
operator->
没有内置的 C + + 操作符 返回什么的。重载的 C + + 操作符返回某些内容,以至于操作符符号是函数调用的语法糖。
相反,运算符都是 评估到某个东西。那个东西有定义良好的 价值和 类型。甚至函数调用操作符 void operator()(/*params*/)也是 void类型。
void operator()(/*params*/)
void
例如,+'a'是 int类型,其值在平台上编码为 'a'。
+'a'
int
'a'
如果你的问题是“ C + + 运算符可以有 void返回类型吗?”那么答案肯定是肯定的。
尽管它们可能不是你所想的 没错,但是请注意,delete和 delete[] C + + ‘ keywords’实际上是 操作员; 它们被定义为具有 void返回类型——这意味着它们是 评估 to nothing (也就是 没有‘ something’)。
delete
delete[]
来自 首选:
void operator delete ( void* ptr ) noexcept; void operator delete[]( void* ptr ) noexcept;
你可以定义一个特殊的 operator void()转换函数,编译器甚至会警告你 T到 void的转换函数 将永远不会被使用:
operator void()
T
#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()! }
由 [ class.conv.fct ]/1管辖
[ ... ] 转换函数从不用于转换(可能 Cv 限定的) 对象到同一对象(可能是 cv 限定的) Type (或对它的引用) ,指向一个(可能是 cv 限定的)基类 或者 到(可能是 cv 限定的) void . < sup > 117 (117) 属性的标准转换 重载解析的目的([ over.best. ics ] ,[ over.ics.ref ])和 因此,初始化([ dcl.init ])和显式强制转换 转换为 void不调用任何转换函数 ([ expr.static.cast ]) . 即使从未直接调用来执行 转换,此类转换函数可以声明并且可以 可能通过调用虚拟转换函数来达到 在基础课上。
[ ... ] 转换函数从不用于转换(可能 Cv 限定的) 对象到同一对象(可能是 cv 限定的) Type (或对它的引用) ,指向一个(可能是 cv 限定的)基类 或者 到(可能是 cv 限定的) void . < sup > 117
(117) 属性的标准转换 重载解析的目的([ over.best. ics ] ,[ over.ics.ref ])和 因此,初始化([ dcl.init ])和显式强制转换 转换为 void不调用任何转换函数 ([ expr.static.cast ]) . 即使从未直接调用来执行 转换,此类转换函数可以声明并且可以 可能通过调用虚拟转换函数来达到 在基础课上。
但是,如上所示,您仍然可以使用显式的 .operator void()语法调用它。
.operator void()
吹毛求疵的是,操作员不会返回任何东西。它们只是我们用来在语言中创建表达式的词汇元素。现在,表达式具有类型并且可以计算为值,我假设这就是您所说的运算符“返回值”的意思。
是的。有类型为 void的 C + + 表达式(因此不计算任何值)。有些是显而易见的,有些则不那么显而易见。一个很好的例子就是
throw std::runtime_error()
throw是 C + + 语法下的一个表达式。您可以在其他表达式中使用它,例如在条件表达式中
throw
return goodStatus() ? getValue() : throw std::runtime_error();
抛出表达式的类型是 void。显然,由于这只会导致执行迅速转移到其他地方,因此表达式没有任何值。
我假设您讨论的是操作符函数,而不是作为语言的语法单位的操作符。
如果在任何类型上重载运算符,实际上可以返回所需的任何内容。
这也很有意义,因为像 * 或()这样的操作有时可能非常直观地不返回它们的输入类型。想象一下,将一个复数类型与一个实数类型相乘。或从集合中返回元素的运算符。
您还可以重载 + + 和——运算符,使其不返回任何内容,从而消除了标准版本所具有的副作用和表达式值的 非常错误倾向性混合。
该语言定义的运算符(内置)是用于执行不同类型计算的令牌:
等等。清单可以是非常广泛的。
在像 这个或 这个这样的语言引用中,它们不一定被引用为返回什么,只是执行一个算术或逻辑 行动,一个可以修改变量的比较,等等。
由于这个操作会产生某个值,因此操作符可以将其解释为“返回”,但它与函数返回值不同。
另一方面,重载运算符可以用某种类型的返回值定义,即使返回值可以为 void,所以,不,并非所有运算符在 C + + 中都返回某个值。
考虑下面两个例子:
int multiply (int a, int b) { return a*b; } void multiply_void(int a, int b) { cout << a*b; //or cout << multiply(a,b); }
第一个函数将返回一个可以被另一个函数使用的整数值。 该值将返回并存储在内存中,以便在必要时使用。如果没有,它对人类来说是看不见的,只是快乐地坐在记忆里。
第二个函数将输出到默认的输出设备(通常是控制台)。 乘法运算符返回的值传递给输出设备。 函数 multi_ void 不返回实际值。
所有操作员返回一些东西。它们被称为操作符,因为它们操作某些东西,因此它们将返回某些东西。那些不返回某些东西的操作员不能被称为操作员。根据具体情况,它们或者返回一些值,或者返回 True 或 False。
运算符本身不必返回任何东西。函数调用返回值。运算符可以产生值。 运算符有时可以调用函数,例如:
•函数调用操作符。
•转换为函数调用的重载操作符。
•作为 新表达式的一部分调用的操作符 new 是一个函数调用。
我提到函数调用的唯一目的是澄清结果和返回。基于对 [ expr ]中所有126个“ return”的实例和从中衍生出来的单词的研究,本节似乎谨慎地使用 return 这个词来指代:
•函数调用的结果
•与协同程序有关的控制流方面
好了,关于结果与回报,这已经够迂腐的了。
C + + 操作符是否返回某些内容取决于您如何使用它们。内置的 C + + 运算符返回一些值,直到并且除非强制返回 void。