7

次のマクロを使用します。

#define ASSERT_IF_TEMP(expr) static_assert(?, "Is temporary!");

疑問符は何を付ければいいですか?

4

2 に答える 2

12

まず、明確にする必要があります。「一時的」とはどういう意味ですか?

多くの人は、一時的なことを言うとき、異なることを意味します。技術的に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
于 2011-05-24T17:40:47.170 に答える
5

編集

私のアプローチは、あなたが言ったコードが機能せず、論理的に逆になっているのとまったく同じことをしていることに気づきました。

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

それがあなたの期待に反してどのような状況で機能するかについて正確に詳しく説明していただけますか?


次のような参照折りたたみルールを利用できます。

std::is_rvalue_reference<decltype((expr))&&>::value

exprが何らかの(おそらくconst)型の左辺値である場合Tdecltype((expr))はに解決されT&T& &&に折りたたまれて元に戻りT&ます。

それ以外の場合、exprが何らかのタイプのxvalueである場合、はTdecltype((expr))になりT&&、はになりT&& &&ますT&&

それ以外の場合は、exprあるタイプのprvalueになりTdecltype((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");
于 2011-05-24T11:31:06.273 に答える