在'requires expression'看来,未计算的操作数是什么?
What is an unevaluated operand in the way a 'requires expression' sees it?
标准[expr.prim.req.general]中的注释2指出:
出现在需求体中的表达式是未赋值的操作数。
简单地说,未求值的操作数是未求值的操作数。
考虑以下代码:
#include <iostream>
int fun(int) { return 5; }
template<typename R>
struct T { static R x; };
int main() {
std::cout << fun(T<int>::x) << std::endl; // Line A
std::cout << requires { fun(T<int &&>::x); } << std::endl; // Line B
//std::cout << requires { fun(T<int &&&>::x); } << std::endl; // Error: Line C
}
毫无疑问,行A与预期的类型相匹配,并且编译良好。
行B与预期类型不匹配(-l和-r值不匹配(,但编译良好。
按照同样的推理,C行虽然包含一个明显的错误,但应该编译,因为操作数不应该被求值。不用说,我故意在这里创建一个语法错误的语句。Clang11和gcc10.2正确识别引用到引用错误。但是,在我的理解中,编译器正在进行模板推导,而语句应该是未求值的。
我的问题是:为什么fun(T<int &&&>::x);
在我的代码中没有被赋值?相反,它正在被评估和模板推导。
最接近的答案是:这里和这里——但它们都是"未定义的行为"。我无法在代码的上下文中解释它们。我目前的猜测是,模板推导不属于未赋值操作数的类别。
表达式仍然需要语法正确(如中所述,符合标准所述的C++语法(,是否进行求值。根据语法,int&&&
无效。(没有ref限定符ref限定符(
(您可以通过将左值传递给接收T&&
的模板来获得这一点,但它将通过引用折叠而变为T&
,但很明显,它是对引用的右值引用,而不是相反的方式——int&&&
是模糊和无意义的(
未赋值的操作数通常是一个用于推断类型信息的表达式,而不是用于其副作用(而丢弃的值表达式仅用于其副效果(。未赋值操作数的其他示例:
T x;
auto typeInfo = typeid(x); // x is unevaluated
auto x_size = sizeof(x); // x is unevaluated
在上面的例子中,似乎很明显,x
并没有真正做到,因为我们只是命名一个变量,但考虑到typeid
或sizeof
的参数可以是任何表达式!表达式不会有任何副作用,因为它是未赋值;在这些情况下,我们只关心结果表达式的类型。
在需要表达式的情况下,需求体(大括号之间的位(需要 表达式对于所有编译器来说,您本可以编写requires{abra;!?...-cadabra}
而不是requires{fun(T<int &&&>::x);}
,但它们同样无效。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 如何计算文件中的"columns"数?
- 计算排序向量的向量中唯一值的计数
- 如何使用 std::累积在 C++ 中计算总和立方体
- 控制允许动态运行c++的并发操作数
- 使用Qt C++计算类似Git的SHA1哈希
- OpenCV C++.快速计算混淆矩阵
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- C++如何计算用户输入的数字中的偶数位数
- C++ 带有向量的 IF 计算操作数
- 是否允许三元运算符在C++中计算两个操作数?
- 基本类型变量的赋值计算序列,右操作数引发异常
- 如何计算重载运算符在具有特定类型操作数的代码库中使用的次数
- 保存计算的操作数
- 计算具有两个以上操作数的后缀表达式时出现问题
- C语言中等优先级操作数的计算顺序