C++ 如何测试表达式是否为临时表达式?

C++ 如何测试表达式是否为临时表达式?,c++,c++11,static-assert,C++,C++11,Static Assert,使用以下宏: #define ASSERT_IF_TEMP(expr) static_assert(?, "Is temporary!"); 我应该用什么作为问号?编辑 我意识到我的方法与您所说的代码完全相同,只是逻辑上颠倒了: std::is_lvalue_reference<decltype((expr))>::value 首先,我们应该澄清:你所说的“暂时”是什么意思 很多人说“暂时”的时候,意思不同。从技术上讲,int()并不是一个临时术语,但大多数人会将其包含在他们自己

使用以下宏:

#define ASSERT_IF_TEMP(expr) static_assert(?, "Is temporary!");
我应该用什么作为问号?

编辑 我意识到我的方法与您所说的代码完全相同,只是逻辑上颠倒了:

std::is_lvalue_reference<decltype((expr))>::value

首先,我们应该澄清:你所说的“暂时”是什么意思

很多人说“暂时”的时候,意思不同。从技术上讲,
int()
并不是一个临时术语,但大多数人会将其包含在他们自己对该术语的理解中。从技术上讲,给定
std::字符串s
,则移动也不是临时的,但您可能希望将其视为宏的一部分

我上面提到的第一种“临时性”实际上是“价值表达”。这些是
std::string(“foo”)
int()
类的东西,但不是
move(s)
,当然也不是
s
类的东西。
decltype
操作符为我上面提到的第一类“临时对象”生成一个非引用类型。对于第二类,
move(s)
,即xvalue,它将生成一个右值引用。对于“非临时性”,即
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
#定义是左值(…)标准::是左值参考::值
#定义为值(…)标准::为值参考::值
#定义是_PRVALUE(…)!std::is_reference::value

表达式的结果总是暂时的。@Clinton:你能解释一下为什么要这样做吗?@Neil:胡说。如果我有一个
char*ptr=some_pointer()
,则表达式
*ptr
是一个左值。@Neil Butterworth了解临时的一些定义。从实用的角度来看,temporary对应于标准所称的右值,某些表达式的结果是左值。如果在堆栈(esp+偏移量)中而不是在堆中,则可以断言某些内容是临时的?感谢您提供了非常详细的答案。我实际上在寻找prvalues,因为在将它们传递给函数之前,可以通过将它们包装在lambda中(从而延迟它们的求值)来省略副本。我认为为其他事情这样做是浪费时间。有没有办法区分std::move(x)和std::move(x())之间的区别?(后者得益于延迟评估)。
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");
#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