в Раздел 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).
Извините, это был не вопрос … Я прав? Следует ли обновить ссылку, чтобы прояснить это поведение?
Да, вы правы, это ошибка, это похоже на Является 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 хотя при чем тут неопределенные значения Я не уверен.
Других решений пока нет …