Other operators
其他操作员
Operator name | Syntax | Overloadable | Prototype examples (for class T) |
---|---|---|---|
Inside class definition | Outside class definition | ||
function call | a(a1, a2) | Yes | R T::operator()(Arg1 &a1, Arg2 &a2, ... ... |
comma | a, b | Yes | T2& T::operator,(T2 &b |
ternary conditional | a ? b : c | No | N/A |
解释
大函数调用
运算符为任何对象提供函数语义。
大三元条件
运算符检查第一个表达式的布尔值,并根据结果值计算并返回第二个或第三个表达式。
内置函数调用操作符
函数调用表达式,如E(A1, A2, A3)
,由一个表达式组成,该表达式将功能,,,E
,后面可能是空的表达式列表。A1, A2, A3, ...
,括号内。
命名函数的表达式可以是。
引用函数的%29 l值表达式
B%29指向函数的指针
C%29显式类成员访问选择成员函数的表达式
D%29隐式类成员访问表达式,例如在另一个成员函数中使用的成员函数名称。
指定的函数%28或成员%29名称E
可能会超载,过载分辨率规则用来决定要调用哪种重载。
如果E
指定一个成员函数,它可能是虚拟的,在这种情况下,将在运行时使用动态调度调用该函数的最终覆盖器。
调用这个函数,
The expression E as well as all expressions A1, A2, A3, etc, provided as arguments are evaluated in arbitrary order, unsequenced with respect to each other. | (until C++17) |
---|---|
The expression E is sequenced before each of the expressions A1, A2, A3 as well as default arguments, if any. The argument expressions are evaluated in arbitrary order, indeterminately sequenced with respect to each other. | (since C++17) |
之后,使用相应的参数初始化每个函数参数。隐式转换必要的话。如果调用成员函数,则this
指向当前对象的指针被转换,就像通过显式转换到this
函数所期望的指针。每个参数的初始化和销毁都发生在调用者的上下文中,这意味着,例如,如果参数的构造函数抛出异常,则不考虑函数中定义的异常处理程序,即使是函数-try块。如果函数是变量函数,默认参数提升应用于由省略号参数匹配的所有参数。它是实现定义的寿命参数的结束时,定义它的函数返回或结束封闭的完整表达式。
函数调用表达式的返回类型是所选函数的返回类型,它使用静态绑定%28确定,忽略virtual
关键字%29,即使%27实际调用的覆盖函数返回不同的类型。这允许重写函数返回从基函数返回的返回类型派生的类的指针或引用,即C++支持协变量返回类型.如果E
指定析构函数,则返回类型为void
...
When an object of class type X is passed to or returned from a function, if each copy constructor, move constructor, and destructor of X is either trivial or deleted, and X has at least one non-deleted copy or move constructor, implementations are permitted to create a temporary object to hold the function parameter or result object. The temporary object is constructed from the function argument or return value, respectively, and the function's parameter or return object is initialized as if by using the non-deleted trivial constructor to copy the temporary (even if that constructor is inaccessible or would not be selected by overload resolution to perform a copy or move of the object). This allows objects of small class types, such as std::complex or gsl::span, to be passed to or returned from functions in registers. | (since C++17) |
---|
如果函数返回函数的lvalue引用或函数的rvalue引用,则函数调用表达式的值类别为lvalue,如果函数返回对象的rvalue引用,则为xvalue,否则为prvalue。如果函数调用表达式是对象类型的prvalue,则它必须具有完整类型,除非没有实现prvalue,例如在C++17%29用作解密型%28或作为内置逗号运算符表达式这是…的操作数。decltype
29%。
函数调用表达式在语法上与值初始化类似。T()
,到功能式铸造表达T(A1)
,并直接初始化临时T(A1, A2, A3, ...)
,在哪里T
类型的名称。
二次
#include <cstdio>
struct S
{
int f1(double d) {
printf("%f \n", d // variable argument function call
}
int f2() {
f1(7 // member function call, same as this->f1()
// integer argument converted to double
}
};
void f() {
puts("function called" // function call
}
int main()
{
f( // function call
S s;
s.f2( // member function call
}
二次
产出:
二次
function called
7.000000
二次
内置逗号运算符
在逗号表达式中E1, E2
,表达E1
计算结果,并在对表达式进行评估之前完成其副作用。E2
开始%28注意:用户定义的operator,
在C++17%29之前不能保证测序%29%28。
逗号表达式的结果的类型、值和值类别正是第二个操作数的类型、值和值类别,E2
.如果E2
是临时表达式%28,因为C++17%29,表达式的结果是临时表达式%28自C++17%29。如果E2
是一点字段,结果是一点字段。
各种逗号分隔列表中的逗号,例如函数参数列表%28f(a, b, c)
%29和初始化程序列表int a[] = {1,2,3}
,不是逗号操作符。如果逗号运算符需要在这种上下文中使用,则必须使用括号:f(a, (n++, n+b), c)
...
二次
#include <iostream>
int main()
{
int n = 1;
int m = (++n, std::cout << "n = " << n << '\n', ++n, 2*n
std::cout << "m = " << (++m, m) << '\n';
}
二次
产出:
二次
n = 2
m = 7
二次
条件算子
计算条件运算符的第一个操作数,上下文转换到bool
在完成第一个操作数的值评估和所有副作用之后,如果结果是true
,计算第二个操作数。如果结果是false
,计算第三个操作数。
条件表达式的类型和值类别。E1 ? E2 : E3
根据下列规则确定:
1%29E2
或E3
有型void
,则下列一项必须为真,或程序格式不正确:
1.1%29E2
或E3
%28但不是%29都是%28--可能是括号内的%29抛出条件运算符的结果具有其他表达式的类型和值类别。如果另一个表达式是位场,结果是有点字段。这类条件运算符在C++11中常用。常数规划在C++14之前。
1.2%29两者E2
和E3
类型void
%28包括当它们都是抛出表达式%29时的情况。结果是类型的prvalue。void
...
2) Otherwise, if E2 or E3 are glvalue bit-fields of the same value category and of types cv1 T and cv2 T, respectively, the operands are considered to be of type cv T for the remainder of this section, where cv is the union of cv1 and cv2. | (since C++14) |
---|
3%29否则,如果E2
和E3
有不同的类型,其中至少有一种类型是%28可能是cv限定%29类类型,或者两者都是相同值类别的glvalue,并且具有除cv限定外的相同类型,然后尝试形成隐式转换序列忽略成员访问,操作数是否为位字段,或转换函数是否自C++14%29以来被删除%28。从每个操作数到目标类型
由另一个操作数确定,如下所述。一个操作数%28调用它X
29%TX
可以转换为目标类型
其他操作数%28调用它Y
29%TY
详情如下:
3.1%29Y
是一个lvalue,目标类型是TY&
,引用必须直接绑定到lvalue;
3.2%29Y
是xvalue,目标类型是TY&&
,引用必须直接绑定;
3.3%29Y
是一个prvalue,或者如果不能形成上述转换序列,并且至少有一个TX
和TY
是%28可能是cv限定%29类类型,目标类型是Y
在应用lvalue-to-rvalue、数组到指针和函数到指针之后,标准转换
3.4%29如果两个序列都可以形成%28E2到目的型E3,E3到目标类型E2%29,或者只能形成一个,但这是模棱两可的转换序列,程序是错误的。
3.5%29如果完全可以形成一个转换序列%28请注意它可能仍然是错误的,例如由于访问违规%29,转换序列被应用,转换操作数被用于代替原始操作数,以替代这个描述的剩余操作数%28开始于%284%29%29。
3.6%29如果不能形成转换序列,则操作数将保持不变,用于本说明的其余部分。
4%29E2
和E3
是相同类型和相同值类别的glvalue,则结果具有相同的类型和值类别,并且是一个位字段(如果至少是其中之一)。E2
和E3
有点野。
5%29否则,则结果为prvalue。如果E2
和E3
不具有相同类型,并且具有%28可能是cv-限定%29类类型,则使用下面的内置候选项执行重载解析,以尝试将操作数转换为内置类型。如果过载解析失败,则程序的格式不正确.。否则,在步骤6中应用所选择的转换,并使用转换的操作数代替原始操作数。
6%29将lvalue到rvalue、数组到指针和函数到指针的转换应用于五操作数.。然后,
6.1%29E2
和E3
现在有相同的类型,结果是该类型的一个prvalue,指定一个临时对象%28,直到C++17%29,其结果对象是%28,因为C++17%29复制初始化了从任何经过计算后选择的操作数。E1
...
6.2%29E2
和E3
具有算术或枚举类型:常用算术变换
都是为了把他们带到共同类型
,这种类型就是结果。
6.3%29E2
和E3
是指针,或者一个是指针,另一个是空指针常量,然后应用指针转换和限定转换将它们转换为公共类型,而该类型就是结果。
6.4%29E2
和E3
是指向成员的指针,或者一个是指向成员的指针,另一个是空指针常量,然后应用指针到成员的转换和限定转换将它们转换为公共类型,结果就是该类型。
6.5%29E2
和E3
为空指针常量,其中至少有一个为类型。std::nullptr_t
,则结果%27s类型为std::nullptr_t
...
6.6%29在所有其他情况下,这个计划都是错误的.
对于每一对提升的算术类型L和R,以及对于每种类型P(其中P是指针、指针到成员或范围内的枚举类型),下列函数签名参与在上述规则的步骤5中执行的过载解析:
LR operator?:(bool, L, R | | |
---|---|---|
P operator?:(bool, P, P | | |
的结果常用算术变换在L
和R
运算符“?:”不能过载,这些函数签名只存在于过载解析中。
条件运算符的返回类型也可以作为二进制类型特征访问。std::common_type
...
二次
#include <string>
#include <stdexcept>
#include <iostream>
struct Node
{
Node* next;
int data;
// deep-copying copy constructor
Node(const Node& other)
: next(other.next ? new Node(*other.next) : NULL)
, data(other.data)
{}
Node(int d) : next(NULL), data(d) {}
~Node() { delete next ; }
};
int main()
{
// simple rvalue example
int n = 1>2 ? 10 : 11; // 1>2 is false, so n = 11
// simple lvalue example
int m = 10;
(n == m ? n : m) = 7; // n == m is false, so m = 7
// throw example
std::string str = 2+2==4 ? "ok" : throw std::logic_error("2+2 != 4"
std::cout << "n = " << n << "\nm = " << m << "\nstr = " << str; //output the result
}
二次
产出:
二次
n = 11
m = 7
str = ok
二次
标准库
标准库重载中的许多类operator()
用作函数对象。
operator() | deletes the object or array (public member function of std::default_delete) |
---|---|
operator() | returns the sum of two arguments (public member function of std::plus) |
operator() | returns the difference between two arguments (public member function of std::minus) |
operator() | returns the product of two arguments (public member function of std::multiplies) |
operator() | returns the result of the division of the first argument by the second argument (public member function of std::divides) |
operator() | returns the remainder from the division of the first argument by the second argument (public member function of std::modulus) |
operator() | returns the negation of the argument (public member function of std::negate) |
operator() | checks if the arguments are equal (public member function of std::equal_to) |
operator() | checks if the arguments are not equal (public member function of std::not_equal_to) |
operator() | checks if the first argument is greater than the second (public member function of std::greater) |
operator() | checks if the first argument is less than the second (public member function of std::less) |
operator() | checks if the first argument is greater than or equal to the second (public member function of std::greater_equal) |
operator() | checks if the first argument is less than or equal to the second (public member function of std::less_equal) |
operator() | returns the logical AND of the two arguments (public member function of std::logical_and) |
operator() | returns the logical OR of the two arguments (public member function of std::logical_or) |
operator() | returns the logical NOT of the argument (public member function of std::logical_not) |
operator() | returns the result of bitwise AND of two arguments (public member function of std::bit_and) |
operator() | returns the result of bitwise OR of two arguments (public member function of std::bit_or) |
operator() | returns the result of bitwise XOR of two arguments (public member function of std::bit_xor) |
operator() | returns the logical complement of the result of a call to the stored predicate (public member function of std::unary_negate) |
operator() | returns the logical complement of the result of a call to the stored predicate (public member function of std::binary_negate) |
operator() | calls the stored function (public member function of std::reference_wrapper) |
operator() | invokes the target (public member function of std::function) |
operator() | lexicographically compares two strings using this locale's collate facet (public member function of std::locale) |
operator() | compares two values of type value_type (public member function of std::map::value_compare) |
operator() | compares two values of type value_type (public member function of std::multimap::value_compare) |
operator() | executes the function (public member function of std::packaged_task) |
operator() | advances the engine's state and returns the generated value (public member function of std::linear_congruential_engine) |
operator() | generates the next random number in the distribution (public member function of std::uniform_int_distribution) |
标准库中的任何类都不会重载逗号运算符。Boost库使用operator,
在助推,分配、助推、精神和其他图书馆。数据库访问库沙基也是过载operator,
...
缺陷报告
以下行为更改缺陷报告追溯应用于先前发布的C++标准。
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 1550 | C++98 | parenthesized throw-expression not allowed in ?: if other operand is non-void | parenthesized throw-expressions accepted |
CWG 1560 | C++98 | void operand in ?: caused gratuitous l-to-r conversion on the other operand, always resulting in rvalue | ?:with a void can be lvalue |
CWG 1932 | C++14 | same-type bit fields were missing in ?: | handled by underlying types |
CWG 1895 | C++14 | unclear if deleted or inaccessible conversion function prevents conversion in ?:, and conversions from base class to derived class prvalue were not considered | handled like overload resolution |
另见
运算符优先...
操作者超载...
公共算子
*。
分配增量递减算术逻辑比较成员访问其他
a=b a+=b a-=b a%2A=b a/=b a%=b a&=b a=b a^=b a<=b a>>=b.+a-a+a-+a-+a-a+b a-b a%2Ab a/b a%b~a&b ab^b a<<b a>>b.%21 a&b a&b ab a=b a%21=b a<b a>b a<=b a>=b a乙%2AA&A->b A.B a->%2Ab a.%2AA%28...%29 a,b?*
特殊运算符
静态[医]强制转换将一种类型转换为另一种相关类型动态。[医]继承层次结构中的强制转换[医]强制转换添加或删除cv限定符,重新解释[医]CAST将类型转换为不相关的类型C风格的强制转换通过混合静态方式将一种类型转换为另一种类型[医]卡斯特[医]重释[医]强制转换新创建具有动态存储持续时间的对象,删除删除以前由新表达式创建的对象,并释放获得的内存区域大小查询类型的大小...查询参数Pack%28的大小,因为C++11%29 Tyid查询类型no的类型信息,除了检查。表达式可以抛出异常%28,因为C++11%29查询对齐要求类型为%28,因为C++11%29。
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。