Fra*_*eux 84 c++ language-lawyer
new int;诸如 in 之类的表达式int * x = new int;是一个新表达式。术语“新运算符”似乎可以与“新表达式”互换使用,例如在这个问题中:“新运算符”和“运算符新”之间的区别?
说new在 new 表达式中使用的关键字是运算符是否正确?为什么或者为什么不?
如果不是,是否还有另一个理由将新表达式称为“新运算符”?
我无法找到构成运算符的权威定义。
我已经理解为对象分配内存的运算符 new和最终可能调用operator new.
Sne*_*tel 141
newinnew int不被视为运算符。它也不被视为不是运营商。
C++ 标准对于“运算符”的构成非常模糊,甚至不一致。当列出运算符(在词法分析和预处理期间定义)时,它会将它们与“标点符号”(例如()一起列出,但通常从未真正给出任何标点符号规则。它new同时作为关键字和运算符列出。它列sizeof在关键字集中但不在运算符集中,但后来将其称为运算符。
这里的要点是 C++ 标准委员会并没有过度关注将词汇世界分为“操作符”和“非操作符”。这是因为真的没有任何必要。没有适用于所有运算符或所有非运算符的语法规则。重要的集合,如可重载运算符的集合,是单独给出的;一次给出一个诸如二进制算术表达式之类的语法规则。
基本上,“运算符”不是对 C++ 语言具有正式意义的类别,因此任何分类答案都将基于它的“感觉”。如果您愿意,您可以将其称为运算符,但您也可以将其称为关键字(或标点符号!),语言标准不会与您不一致。
Use*_*ess 16
说
new在new 表达式中使用的关键字是运算符是否正确?为什么或者为什么不?
号的new在一个新的表达式是识别关键字新表达。
一个新的表达 要求的operator new或operator new[]获得存储。它还初始化该存储,并在初始化抛出时取消分配它(使用operator delete或operator delete[])。
有一个明显的区别,它operator new仅被称为可重载的用户可替换函数,而new 表达式不仅仅调用此函数。
参考:7.6.2.8/10 [expr.new]
甲新表达可以通过调用分配函数获得用于对象存储(
[basic.stc.dynamic.allocation])。如果new 表达式因抛出异常而终止,则它可以通过调用释放函数来释放存储空间。如果分配的类型是非数组类型,则分配函数的名称为operator new,释放函数的名称为operator delete。如果分配的类型是数组类型,则分配函数的名称为operator new[],释放函数的名称为operator delete[]。
通过反例考虑,我们定义了两者
T operator+(T, T);
void* T::operator new(std::size_t);
Run Code Online (Sandbox Code Playgroud)
对于某些类型 T,然后以任一形式添加:
T a, b;
T c = a + b;
T d = T::operator +(a, b);
Run Code Online (Sandbox Code Playgroud)
是相同的。中缀符号只是操作符调用的语法糖。
然而,分配的行为非常不同:
T *p = new T;
// does much more than
void *v = T::operator new(sizeof(T));
Run Code Online (Sandbox Code Playgroud)
所以调用new-expression语法糖来调用operator new. 因此,new关键字不是简单地选择要调用的函数。它不能,或者它必须提到operator delete也可能被调用的函数。
t.n*_*ese 12
我只会称它为新表达式以避免混淆void* operator new ( std::size_t count ),它只在新表达式 发票过程中分配内存(分配内存、起始生命周期、调用构造函数)。
问题new在于它不仅仅是调用operator new. 这是一个有点混乱,因为x + y在+只有通话operator +。
这是由[expr.new] 控制的,它清楚地区分了new 表达式和 new 表达式如何通过调用名为的分配函数来获取存储空间operator new。特别是,来自 [expr.new]/8 [强调我的]:
甲新表达式可以得到存储通过调用分配函数为对象([basic.stc.dynamic.allocation])。如果 new 表达式因抛出异常而终止,则它可以通过调用释放函数来释放存储空间。如果分配的类型是非数组类型,则分配函数的名称是
operator new,释放函数的名称是 operator delete。如果分配的类型是数组类型,则分配函数的名称为 operatornew[],释放函数的名称为 operatordelete[]。
说
new在 new 表达式中使用的关键字是运算符是否正确?
特别是,[expr.new]/4的示例虽然不规范,但将该函数描述为运算符函数; “[...]new操作员”:
[...] 相反,可以使用新运算符的显式括号版本 [...]
No.
Well, sort of yes, in the sense that there exist people who consider new in new int to be an operator. However, this opinion is (mostly) at odds with the standard.
Firstly, [lex.operators/1] lists the operators in the language. Don't be fooled into thinking that these are just "preprocessing operators", either; no such distinction exists in the sense of lexical operators. It wouldn't make sense, either, since you cannot (for example) ++ a macro.
new is, in fact, a keyword (per [lex.key/1]).
Next, let's look at new-expression itself. This is where things get a little more wooly. There is, for example, the following wording in [expr.new/4]:
Instead, the explicitly parenthesized version of the new operator can be used to create objects of compound types
I consider this to be an editorial error, since it is at odds with the definitions provided above, and does not occur anywhere else in that section.
Then we come to operator overloading. In its grammatical production for an operator declaration, the terminal listing things (including new) is named operator ([over.oper.general/1]). I don't think we need to worry about this. The names of terminals in the grammar have never been intended to introduce definitions of terms. After all, you have and-expression that _doesn't need to be a bitwise AND operation; it can just be an equality-expression:
and-expression:
equality-expression
and-expression&equality-expression
It's common to define grammars like this, and it certainly doesn't mean that every equality-expression is somehow to be considered an invocation of the bitwise AND operator.
Finally, some have claimed that the following wording (also in the operator overloading section) is proof that new is somehow now, in isolation, magically an operator:
The operators
new[],delete[],(), and[]are formed from more than one token
我对他们说,不仅new没有列出,而且这显然是在更广泛的意义上使用“运算符”一词,即“可以重载的事物”,即使new其本身仍然不是运算符。它也在一个非规范性的注释中,它应该告诉你所有你需要知道的。
而且,正如您自己指出的那样,我们已经考虑operator new成为其他东西。
虽然我知道您正在寻找语义答案,但就意见而言,我会说它是一个“关键字”(因为它显然是保留的),并且我假设我们都知道它只是 C++ 的内存分配构造。也就是说,当我想到 C++ 的“操作符”时,我倾向于想到具有可以为特定类型覆盖的一组输入/输出的函数。new 对所有类型都是相同的(更令人困惑的是它可以被覆盖)。
不确定 cppreference 的官方如何,但是:
new 表达式通过调用适当的分配函数来分配存储。如果 type 是非数组类型,则函数名称为 operator new。如果 type 是数组类型,则函数名是 operator new[]
https://en.cppreference.com/w/cpp/language/new
似乎接着 thatnew <type>是分配内存的表达式,而new是该表达式的运算符。
使用相同的逻辑:
sizeof是表达式的“运算符” sizeof(<type>)(虽然sizeof是“编译时”运算符,与我们习惯的有点不同)+ 是表达式的运算符 <type> <operator> <type>throw 是表达式的运算符 throw <throwaable>| 归档时间: |
|
| 查看次数: |
7616 次 |
| 最近记录: |