Должен ли оператор доступа к члену rvalue быть xvalue?

в Раздел cpprefernce: категории значений, в нем говорится, что «член выражения объекта, где a является значением r, а m является элементом не статических данных не ссылочного типа», является значением xvalue. В стандарте (я нашел в: N4140, проект стандарта C ++ 14) в нем говорится (на странице 87), что «выражение является значением xvalue, если оно является … выражением доступа к члену класса, обозначающим нестатический элемент данных не ссылочного типа, в котором выражение объекта является значением xvalue».

Я хотел проверить мое понимание этого с помощью следующего кода:

struct B { // B for Boring...
int i{0};
};

template <typename T> struct V {
V() { cout << "V" << endl; }
};

template <typename T> struct V<T &> { // Partial Specialization
V() { cout << "V&" << endl; }
};

template <typename T> struct V<T &&> { // Partial Specialization
V() { cout << "V&&" << endl; }
};

int main() {
int i{1};
V<decltype((1))> v1;       // V
V<decltype((i))> v2;       // V&
V<decltype((move(i)))> v3; // V&&

V<decltype((B().i))> v4;       // V, why not V&&?
V<decltype((move(B()).i))> v5; // V&& as expected
}

Если мои расчеты верны, то B().i является «членом выражения объекта, где [B()] является rvalue, «и в соответствии со ссылкой, выражение должно быть xvalue, а тип, возвращаемый decltype должен быть int&&, Обратите внимание, что я использую gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)и я попробовал это без флагов и с -std=c++14,

(Чтобы быть ясным, я также проверяю мое понимание «decltype» здесь, но стандарт, с которым я ранее связался, и ссылка согласуются дословно и довольно четко о поведении decltype).

Извините, это был не вопрос … Я прав? Следует ли обновить ссылку, чтобы прояснить это поведение?

5

Решение

Да, вы правы, это ошибка, это похоже на Является f().a[0] xvalue? но этот случай конкретно касался массивов, которые были вырезаны в [Expr.sub] p1 который сказал, что результат был lvalue, но считается дефектом. В противном случае применяется та же логика.

Мы можем видеть это было исправлено в clang 4.0 и если мы проверим лязг < 4.0 в прямом эфире, мы получаем те же самые несоответствующие результаты, которые вы видите из GCC меньше, чем самая ГОЛОВА но лязг 4.0 и> живи это также исправлено.

Также обратите внимание на проблему из Является f().a[0] xvalue? также фиксируется только в GCC HEAD.

Также обратите внимание, что [Expr.ref] P4.2

… Если E1 является lvalue, то E1.E2 является lvalue; если E1 является значением x, то E1.E2 является значением x; в противном случае это prvalue …

после C ++ 11 изменилось на этот:

… Если E1 является lvalue, то E1.E2 является lvalue; в противном случае E1.E2 является значением xvalue. …

Похоже, что изменение было изначально частью DR 616 хотя при чем тут неопределенные значения Я не уверен.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]