次のマクロを使用します。
#define ASSERT_IF_TEMP(expr) static_assert(?, "Is temporary!");
疑問符は何を付ければいいですか?
次のマクロを使用します。
#define ASSERT_IF_TEMP(expr) static_assert(?, "Is temporary!");
疑問符は何を付ければいいですか?
まず、明確にする必要があります。「一時的」とはどういう意味ですか?
多くの人は、一時的なことを言うとき、異なることを意味します。技術的にint()
は一時的なものではありませんが、ほとんどの人はそれらをその用語の独自の意味に含めます。技術的には、与えられたstd::string s;
場合move(s)
も一時的なものではありませんが、マクロと1つとして扱いたい場合があります。
私が上で述べた最初の種類の「一時的」は、実際には「prvalue式」です。それらはstd::string("foo")
またはint()
種類のものですが、move(s)
また(確かに)s
種類のものではありません。演算子は、上記decltype
で説明した最初の種類の「一時的」の非参照型を生成します。move(s)
xvaluesである2番目の種類の場合、右辺値参照が生成されます。そして、「非一時的」、つまりs
ケースの場合、左辺値の参照が生成されます。
要約すると、3つの正確なマクロを定義し、それらから選択できます。
#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
が何らかの(おそらくconst)型の左辺値である場合T
、decltype((expr))
はに解決されT&
、T& &&
に折りたたまれて元に戻りT&
ます。
それ以外の場合、expr
が何らかのタイプのxvalueである場合、はT
、decltype((expr))
になりT&&
、はになりT&& &&
ますT&&
。
それ以外の場合は、expr
あるタイプのprvalueになりT
、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");