使用以下宏:
#define ASSERT_IF_TEMP(expr) static_assert(?, "Is temporary!");
问号应该填什么?
使用以下宏:
#define ASSERT_IF_TEMP(expr) static_assert(?, "Is temporary!");
问号应该填什么?
首先我们要澄清:你所说的“临时”是什么意思?
很多人说临时的意思不同。从技术上讲,int()
这不是暂时的,但大多数人都会将它们包含在他们自己的含义中。从技术上讲, given std::string s;
, thenmove(s)
也不是临时的,但您可能希望将其与宏视为一个。
我上面提到的第一种“临时”实际上是“prvalue 表达式”。那些是std::string("foo")
或int()
类型的东西,但不是move(s)
而且(肯定)不是s
那种东西。该decltype
运算符为我上面谈到的第一种“临时”产生了一个非引用类型。对于第二种move(s)
xvalues,它将产生一个右值引用。对于“非临时人员”,即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
Ifexpr
是某个(可能是 const)类型的左值T
,decltype((expr))
将解析为T&
,T& &&
并将折叠回T&
。
否则, ifexpr
是某种类型的 xvalue T
,decltype((expr))
将会是T&&
,并且T&& &&
会减少到 just T&&
。
否则,expr
将是某种类型的纯右值T
,decltype((expr))
将 yield 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");