如何测试表达式是否为临时表达式
How to test whether expression is a temporary?
使用以下宏:
#define ASSERT_IF_TEMP(expr) static_assert(?, "Is temporary!");
我应该把什么作为问号?
首先我们应该澄清:"临时"是什么意思?
很多人说"暂时"是指不同的意思。从技术上讲,int()
不是暂时的,但大多数人会将其纳入该术语的含义中。从技术上讲,给定std::string s;
,那么move(s)
也不是临时的,但您可能希望将其与宏视为一个。
我上面提到的第一种"临时性"实际上是"prvalue表达式"。这些是std::string("foo")
或int()
类的东西,但不是move(s)
,也(当然)不是s
类的东西。decltype
运算符为我上面谈到的第一类"临时"生成了一个非引用类型。对于第二种move(s)
,即x值,它将产生一个右值引用。对于"非临时性",即s
情况,它将产生左值引用。
总之,我将定义三个精确的宏,你可以从中选择
#define IS_LVALUE(...) std::is_lvalue_reference<decltype((__VA_ARGS__))>::value
#define IS_XVALUE(...) std::is_rvalue_reference<decltype((__VA_ARGS__))>::value
#define IS_PRVALUE(...) !std::is_reference<decltype((__VA_ARGS__))>::value
编辑
我意识到我的方法做的事情和你说的不起作用的代码完全一样,只是逻辑上颠倒了:
std::is_lvalue_reference<decltype((expr))>::value
你能详细说明在什么情况下它会违背你的期望吗?
你可以像这样利用引用折叠规则:
std::is_rvalue_reference<decltype((expr))&&>::value
如果expr
是某个(可能是常量)类型T
的左值,则decltype((expr))
将解析为T&
,而T& &&
将折叠回T&
。
否则,如果expr
是某种类型T
的x值,则decltype((expr))
将是T&&
,并且T&& &&
将减少到仅T&&
。
否则,expr
将是某个类型T
的prvalue,decltype((expr))
将产生T
,因此整个类型将是T&&
。
示例:
template <typename T>
struct is_rvalue : std::is_rvalue_reference<T&&>
{};
struct x {};
x a; const x b{};
static_assert(is_rvalue<decltype((x()))>::value, "x() is an rvalue");
static_assert(!is_rvalue<decltype((a))>::value, "a is an lvalue");
static_assert(!is_rvalue<decltype((b))>::value, "b is an lvalue");
static_assert(is_rvalue<decltype((std::move(a))>::value, "std::move(a) is an rvalue");
相关文章:
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- 编写了一个C++代码来检查表达式是否具有平衡括号并且我的代码未运行.我已经卡了一天了
- 仅通过引用捕获的 lambda 表达式是否保证不会抛出?
- 在 C 和 C++ 中,使用逗号运算符的表达式是否未定义"a = b, ++a;"?
- 布尔表达式是否像使用 if 或 switch 进行分支一样繁琐?
- ranged-for 语句中的表达式是否在每次迭代时计算
- 正则表达式是否足以分析大型文本
- 使用堆栈来确定表达式是否具有平衡圆括号
- 如何正确测试我的后缀表达式是否有效
- C++11 正则表达式是否适用于 UTF-8 字符串
- 新表达式是否会返回指向数组的指针
- 检查一个正则表达式是否涵盖另一个正则表达式
- 动态分配正确对齐的内存:char数组上的新表达式是否合适
- 元正则表达式:测试正则表达式是否只是一个字符串(没有正则表达式"wildcards")
- 检查编译的表达式是否包含所有隐式转换
- 具有未定义行为但从未实际执行的表达式是否会使程序出错
- 频繁执行的表达式是否会缓存其结果
- boost::lambda::bind 表达式是否阻止内联/是否有另一种形式不会?
- 检查表达式是否编译的可移植方法
- lambda 函数/表达式是否支持 constexpr