经常浮现的一个例子是:
sizeof表达式,它不计算表达式,但通过静态类型确定大小.例如 :
int func();
sizeof(func());
Run Code Online (Sandbox Code Playgroud)
这是我思考的极限,所以如果还有其他未评估的背景,那么它们是什么?
5go*_*der 38
幸运的是,该标准有一个方便的列表(§5[expr]8):
在某些情况下,出现了未评估的操作数(5.2.8,5.3.3,5.3.7,7.1.6.2).未评估未评估的操作数.未评估的操作数被视为完整表达式.
让我们详细看看这些.
我将在我的示例中使用以下声明.声明的函数永远不会在任何地方定义,因此如果对它们的调用出现在评估的上下文中,则程序格式错误,我们将得到链接时错误.然而,在未评估的环境中调用它们很好.
int foo(); // never defined anywhere
struct widget
{
virtual ~widget();
static widget& get_instance(); // never defined anywhere
};
Run Code Online (Sandbox Code Playgroud)
typeid§5.2.8[expr.typeid]3:
当
typeid应用于多态类类型的glvalue以外的表达式时,结果引用std::type_info表示表达式的静态类型的对象.Lvalue-to-rvalue(4.1),数组到指针(4.2)和函数到指针(4.3)转换不应用于表达式.如果表达式的类型是类类型,则应完全定义类.表达式是未评估的操作数(第5条).
注意多态类的强调异常(a class至少有一个virtual成员).
因此,这没关系
typeid( foo() )
Run Code Online (Sandbox Code Playgroud)
并为此产生一个std::type_info对象int
typeid( widget::get_instance() )
Run Code Online (Sandbox Code Playgroud)
不是,可能会产生链接时错误.它必须评估操作数,因为动态类型是通过查看vptrat运行时来确定的.
<rant>我发现操作数的静态类型是否具有多态性这一事实会以如此戏剧性但微妙的方式改变运算符的语义,这让我感到非常困惑.</ rant>
sizeof§5.3.3[expr.sizeof]1:
的
sizeof操作者产生在其操作数的对象表示的字节数.操作数是一个表达式,它是一个未评估的操作数(第5章),或带括号的type-id.sizeof在声明所有枚举数之前,运算符不应该应用于具有函数或不完整类型的表达式,其基础类型未固定的枚举类型,此类型的带括号的名称,或者指定位的glvalue -领域.
下列
sizeof( foo() )
Run Code Online (Sandbox Code Playgroud)
非常好,相当于sizeof(int).
sizeof( widget::get_instance() )
Run Code Online (Sandbox Code Playgroud)
也是允许的.但请注意,它sizeof(widget)与多态return类型相当,因此可能不太有用.
noexcept§5.3.7[expr.unary.noexcept]1:
在
noexcept操作员确定的评估是否它的操作数,这是一个未计算的操作数(第5章),可以抛出异常(15.1).
表达方式
noexcept( foo() )
Run Code Online (Sandbox Code Playgroud)
是有效的,并评估为false.
这是一个更实际的例子,也是有效的.
void bar() noexcept(noexcept( widget::get_instance() ));
Run Code Online (Sandbox Code Playgroud)
请注意,只有内部noexcept是操作符,而外部是说明符.
decltype§7.1.6.2[dcl.type.simple]4.4:
说明符的操作数
decltype是未评估的操作数(第5条).
该声明
decltype( foo() ) n = 42;
Run Code Online (Sandbox Code Playgroud)
声明一个n类型的变量int并用值42初始化它.
auto baz() -> decltype( widget::get_instance() );
Run Code Online (Sandbox Code Playgroud)
声明一个baz不带参数和returnsa 的函数widget&.
这就是全部(从C++ 14开始).
标准术语是未评估的操作数,您可以在[expr]中找到它
在某些情况下,出现了未评估的操作数(5.2.8,5.3.3,5.3.7,7.1.6.2).未评估未评估的操作数.未评估的操作数被视为完整表达式.[注意:在未评估的操作数中,可以将非静态类成员命名为(5.1),并且对象或函数的命名本身不要求提供定义(3.2). - 尾注]
typeidsizeofnoexceptauto和decltype和POD类型,如int,char,double等.| 归档时间: |
|
| 查看次数: |
2457 次 |
| 最近记录: |