使用以下宏:
#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");