Чому перший повертає посилання?
int x = 1;
int y = 2;
(x > y ? x : y) = 100;
Поки другий ні?
int x = 1;
long y = 2;
(x > y ? x : y) = 100;
Насправді, друге взагалі не складено - "не оцінено ліворуч від завдання".
Чому перший повертає посилання?
int x = 1;
int y = 2;
(x > y ? x : y) = 100;
Поки другий ні?
int x = 1;
long y = 2;
(x > y ? x : y) = 100;
Насправді, друге взагалі не складено - "не оцінено ліворуч від завдання".
Відповіді:
У виразах немає типів повернення, вони мають тип і - як відомо в останньому стандарті C ++ - категорію значень.
Умовним виразом може бути рівнезначення або ревалю . Це його ціннісна категорія. (Це дещо спрощення, C++11
оскільки у нас є lvalues, xvalues і prvalues.)
У дуже широкому та простому значенні lvalue означає об'єкт у пам'яті та rvalue - це просто значення, яке не обов'язково може бути приєднане до об'єкта в пам'яті.
Вираз присвоєння присвоює значення об'єкту, тому річ, якій призначено, повинна бути значенням .
Щоб умовний вираз ( ?:
) був значенням (знову ж таки, у широкому та простому значенні), другий та третій операнди повинні бути однозначними значеннями . Це пояснюється тим, що тип і значення категорії умовного виразу визначаються під час компіляції і повинні відповідати, чи є умова істинною. Якщо один з операндів повинен бути перетворений на інший тип, щоб відповідати іншому, то умовний вираз не може бути значенням, оскільки результат цього перетворення не був би значенням .
ISO / IEC 14882: 2011 посилання:
3.10 [basic.lval] Значення та оцінки (про категорії цінностей)
5.15 [expr.cond] Умовний оператор (правила щодо того, який тип та значення значення має умовний вираз)
5.17 [expr.ass] Оператори присвоєння та складання присвоєння (вимога, щоб lhs присвоєння повинні бути змінним значенням)
an rvalue is just a value that may not necessarily be *attached* to an object in memory.
Чи можете ви пояснити це більш простим терміном? . Також що ви маєте на увазі під type and value *category*
? Спасибі
prvalue, xvalue, glvalue
це цінні категорії.
true
, this
, enum
цінність. Ці речі є prvalues ("чисті" rvalues), але не живуть в пам'яті.
Тип потрійного ?:
виразу є загальним типом його другого та третього аргументу. Якщо обидва типи однакові, ви отримуєте довідку назад. Якщо вони перетворюються один в одного, один вибирається, а інший конвертується (сприяє в цьому випадку). Оскільки ви не можете повернути посилання lvalue до тимчасової (перетворена / підвищена змінна), її тип є типом значення.
Він не може повернути значення значення, оскільки йому доведеться неявно просувати тип x
відповідності типу y
(оскільки обидві сторони :
не є одним і тим же типом), і з цим він повинен створити тимчасовий.
Вирази 5.17 Оператори призначення та складання операторів
5.17 / 3
Якщо другий і третій операнди мають різні типи, або має або тип (можливо, cv-кваліфікований) клас класу, робиться спроба перетворення кожного з цих операндів у тип іншого. Процес визначення, чи може вираз операнда E1 типу T1 перетворити на вираз операнда E2 типу T2, визначається наступним чином:
- Якщо E2 є значенням: E1 можна перетворити на відповідність E2, якщо E1 можна неявно перетворити (п. 4) у тип "посилання на T2", за умови обмеження, що при перетворенні посилання має пов'язуватися безпосередньо (8.5.3 ) до Е1.
- Якщо E2 є рейтингом, або якщо перетворення, описане вище, неможливо:
- якщо E1 і E2 мають тип класу, а базові типи класів однакові або один є базовим класом іншого: E1 можна перетворити на відповідність E2, якщо клас T2 того ж типу, або базовий клас , клас T1 і cv-кваліфікація T2 є такою ж cv-кваліфікацією, що і, або більша cv-кваліфікація, ніж cv-кваліфікація T1. Якщо застосовується перетворення, E1 змінюється на ревальвінг типу T2, який все ще посилається на оригінальний об'єкт класу-джерела (або відповідний його суб'єкт). [ Примітка: тобто копія не робиться. - кінцева примітка ] шляхом ініціалізації копіювання тимчасового типу T2 від E1 та використання цього тимчасового в якості перетвореного операнда.
В іншому випадку (тобто, якщо
E1
або E2 має тип не класу, або якщо вони обидва мають типи класів, але базові класи не є однаковими, або один базовий клас іншого): E1 може бути перетворений у відповідність E2, якщо E1 може бути неявно перетворений у тип, який мав би вираз E2, якби E2 було перетворено в rvalue (або тип, який він має, якщо E2 є rvalue).Використовуючи цей процес, визначається, чи може другий операнд бути перетворений для відповідності третьому операнду та чи може третій операнд бути перетворений для відповідності другому операнду. Якщо обидва можуть бути перетворені або одна може бути перетворена, але перетворення неоднозначне, програма неправильно формується. Якщо жодне з них не може бути перетворене, операнди залишаються незмінними і виконується подальша перевірка, як описано нижче. Якщо можливе саме одне перетворення, це перетворення застосовується до обраного операнда, а перетворений операнд використовується замість вихідного операнда на решту цього розділу.
5.17 / 4
Якщо другий і третій операнди є значеннями і мають один і той же тип, результат цього типу і є значенням, і це бітове поле, якщо другий або третій операнди є бітовим полем або якщо обидва є бітовими полями поля.
5.17 / 5
В іншому випадку результат - ревальвація. Якщо другий та третій операнди не мають одного типу, або мають або тип класу (можливо, що відповідає кваліфікації cv), роздільна здатність перевантаження використовується для визначення перетворень (якщо такі є), що застосовуються до операндів (13.3.1.2, 13.6) . Якщо роздільна здатність перевантаження не вдається, програма неправильно сформована. В іншому випадку, визначені таким чином перетворення застосовуються, а перетворені операнди використовуються замість вихідних операндів на залишок цього розділу.