Должен ли оператор доступа к члену rvalue быть xvalue? - PullRequest
0 голосов
/ 05 ноября 2018

В разделе 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()] является значением r», и, согласно ссылке, выражение должно быть значением xvalue, а тип, возвращаемый decltype должно быть int &&. Обратите внимание, что я использую gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04), и я попробовал это без флагов и с -std=c++14.

(Для ясности, я также проверяю свое понимание "decltype" здесь, но стандарт, с которым я ранее ссылался, и ссылка, даются дословно и довольно четко о поведении decltype).

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

1 Ответ

0 голосов
/ 05 ноября 2018

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

Мы можем видеть, что это исправлено в clang 4.0 , и если мы проверим clang <4.0 live </a>, мы получим те же самые несоответствующие результаты, которые вы видите из gcc меньше, чем большинство HEAD , но clang 4.0 и> live , это также исправлено.

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

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

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

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

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

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

...