Подтвердить что ты не робот

Эмпирически определить категорию значений выражения С++ 11?

Каждое выражение в С++ 11 имеет категорию значений. Один из значений lvalue, xvalue или prvalue.

Есть ли способ написать макрос, который, учитывая любое выражение в качестве аргумента, приведет к созданию строки "lvalue", "xvalue" или "prvalue", если это необходимо?

Например:

int main()
{
    int x;

    cout << VALUE_CAT(x) << endl; // prints lvalue
    cout << VALUE_CAT(move(x)) << endl; // prints xvalue
    cout << VALUE_CAT(42) << endl; // prints prvalue
}

Как реализовать VALUE_CAT?

4b9b3361

Ответ 1

decltype может возвращать объявленный тип объекта (отсюда и название), но также может использоваться для запроса типа выражения. Однако в последнем случае результирующий тип "скорректирован" в соответствии с категорией значений этого выражения: выражение lvalue приводит к ссылочному типу lvalue, значению x в ссылочном типе rvalue и prvalue только для типа. Мы можем использовать это в наших интересах:

template<typename T>
struct value_category {
    // Or can be an integral or enum value
    static constexpr auto value = "prvalue";
};

template<typename T>
struct value_category<T&> {
    static constexpr auto value = "lvalue";
};

template<typename T>
struct value_category<T&&> {
    static constexpr auto value = "xvalue";
};

// Double parens for ensuring we inspect an expression,
// not an entity
#define VALUE_CATEGORY(expr) value_category<decltype((expr))>::value

Ответ 2

Вы также можете попробовать использовать функцию clang API Classification, чтобы вернуть категорию выражения из clang AST, содержащего выражение. Это, конечно, гораздо сложнее, чем решение @Luc, так как оно требует генерации фактического AST через clang.