Всі оператори C ++, з якими я працював, повертають щось, наприклад, +
оператор повертає результат додавання.
Чи всі оператори C ++ щось повертають, чи є деякі оператори C ++, які нічого не повертають?
Всі оператори C ++, з якими я працював, повертають щось, наприклад, +
оператор повертає результат додавання.
Чи всі оператори C ++ щось повертають, чи є деякі оператори C ++, які нічого не повертають?
+=
повернення void
, але це не рекомендується. Також оператори викликів функцій можуть повернутися, void
і це дійсно
::
нічого не повертає, але мені доведеться проконсультуватися зі стандартом, щоб переконатися.
Відповіді:
Хоча вони, мабуть, не зовсім те, про що ви думаєте, зауважте, що „ключові слова” delete
та delete[]
C ++ насправді є операторами ; і вони визначаються як такі, що мають void
тип повернення - це означає, що вони не оцінюють до нуля (що не є "чимось").
З cppreference :
void operator delete ( void* ptr ) noexcept;
void operator delete[]( void* ptr ) noexcept;
delete
, delete[]
, throw
, (void)x;
Лиття, ліва сторона ,
оператора, з правого боку ,
оператора , що дає void
, А ?:
потрійна , який використовує throw
для одного з плечей, dfri в operator void()
(який був би визначається користувачем),眠りネロク's void operator()()
(певний який був би користувач).
delete
оператор знищує об’єкт, а потім викликає operator delete
. Ergo, то delete
оператор і operator delete
окремі речі :( stackoverflow.com/a/8918942/845092
operator delete
.
Оператори спеціальних типів можуть бути перевантажені, щоб робити найдивніші речі.
наприклад, оператор + повертає результат додавання.
Не обов'язково:
#include <iostream>
struct foo {
int value = 0;
void operator+(int x) {
value += x;
}
};
int main () {
foo f;
f + 3;
}
Тут operator+
додається ліва сторона до value
елемента, і його тип повернення недійсний. Це вигаданий приклад, але, загалом, не повернення чогось із користувацького оператора не є незвичайним.
Єдиний оператор, який може бути перевантажений і який вимагає повернення чогось, про що мені відомо, це operator->
. Він повинен повернути необроблений вказівник або об'єкт, який має operator->
.
operator->
є трохи особливим і потребує повернення або покажчика, або об'єкта, який має operator->
, не впевнений, що є інші винятки
operator*(Matrix const& left, Matrix const& right)
повертається не Matrix
а, а замість цього MatrixMul
, так що якщо вона буде подана в operator+(Matrix const& left, MatrixMul const& right)
операцію, це може бути сплавлене множення-додавання, яке ефективніше, ніж спочатку множення, а потім додавання.
<<
і >>
перевантажуються для операцій вводу-виводу, вони очікують повернення потоку, щоб ви могли їх каскадувати:stream << foo << bar;
Натомість оператори нічого не повертають. Це просто лексичні елементи, які ми використовуємо для створення виразів мовою. Зараз вирази мають типи і можуть обчислюватися значеннями, і я припускаю, що це те, що ви маєте на увазі під операторами, які "повертають речі".
Ну, ну так. Існують вирази C ++ із типом void
(і, отже, не обчислюють жодне значення). Одні очевидні, інші менш. Приємним прикладом буде
throw std::runtime_error()
throw
- це вираз під граматикою C ++. Ви можете використовувати його в інших виразах, наприклад, в умовному виразі
return goodStatus() ? getValue() : throw std::runtime_error();
А тип виразу кидка - це void
. Очевидно, оскільки це просто змушує виконання швидко йти в інше місце, вираз не має значення.
Жоден із вбудованих операторів C ++ щось не повертає . Перевантажені оператори C ++ повертають щось настільки, що позначення оператора є синтаксичним цукром для виклику функції.
Швидше, всі оператори оцінюють щось. Те, що щось має чітко визначене значення , а також тип . Навіть оператор виклику функції void operator()(/*params*/)
є void
типом.
Наприклад, +'a'
це int
тип зі значенням, 'a'
кодованим на вашій платформі.
Якщо ваше запитання: "Чи можуть оператори C ++ мати void
тип повернення?" тоді відповідь, безумовно, так.
I++
не повертає значення. Якщо тип i
- це визначений користувачем тип, цей вираз реалізується як operator++
, що є функцією, яка повертає значення. Ви називаєте це "синтаксичним цукром"; Я називаю це розмежуванням, яке має важливі наслідки.
Ви можете фактично визначити оператор виклику функції, щоб нічого не повертати. Наприклад:
struct Task {
void operator()() const;
};
Ви можете визначити своєрідно operator void()
функцію перетворення, де компілятор буде навіть попередить вас про те , що T
для void
функції перетворення ніколи не буде використовуватися :
#include <iostream>
struct Foo {
operator void() { std::cout << "Foo::operator void()!"; }
// warning: conversion function converting 'Foo' to
// 'void' will never be used
};
int main() {
Foo f;
(void)f; // nothing
f.operator void(); // Foo::operator void()!
}
відповідно до [class.conv.fct] / 1
[...] Функція перетворення ніколи не використовується для перетворення (можливо cv-кваліфікованого) об’єкта в (можливо cv-кваліфікований) того самого типу об’єкта (або посилання на нього), у (можливо cv-кваліфікований) базовий клас такого типу (або посилання на нього), або до (можливо , CV-кваліфікованим)
void
. 117( 117 ) Ці перетворення розглядаються як стандартні перетворення для цілей дозволу на перевантаження ([over.best.ics], [over.ics.ref]) і, отже, ініціалізація ([dcl.init]) та явне приведення. Перетворення в
void
не викликає жодної функції перетворення ([expr.static.cast]). Незважаючи на те, що їх ніколи не викликають безпосередньо для здійснення перетворення, такі функції перетворення можуть бути оголошені і потенційно доступні через виклик функції віртуального перетворення в базовому класі.
Однак, як показано вище, ви все одно можете викликати його, використовуючи явний .operator void()
синтаксис.
Оператори, визначені (вбудовані) мовою, є лексемами, що використовуються для виконання різних видів обчислень:
і так далі. Список може бути дуже великим.
У таких мовних посиланнях, як цей чи цей , на них не обов'язково посилаються як на щось, що повертає, просто виконуючи арифметичну або логічну операцію , порівняння, за допомогою якого змінна може бути змінена тощо.
Оскільки ця операція призводить до деякого значення, воно може інтерпретуватися як "повернене" оператором, але воно відрізняється від значення функції, що повертається.
З іншого боку, перевантажені оператори можуть бути визначені із значенням повернення якогось типу, навіть це може бути порожнім, тож, ні, не всі оператори повертають якесь значення в C ++.
Я припускаю, що ви говорите про функції оператора, а не про оператори як про синтаксичну одиницю мови.
Якщо ви перевантажуєте оператори будь-якого типу, ви можете фактично повернути все, що завгодно.
Це також має великий сенс, оскільки операції, такі як * або (), іноді можуть дуже інтуїтивно не повертати свій тип введення. Уявіть, як помножте складний тип числа на дійсний тип числа. Або оператор, який повертає елемент із колекції.
Ви також можете перевантажити оператори ++ та -, щоб нічого не повертати, таким чином усуваючи надзвичайно схильне до помилок змішування значення побічного ефекту та виразу, яке має стандартна версія.
Ні. Розглянемо ці два приклади тут:
int multiply (int a, int b) {
return a*b;
}
void multiply_void(int a, int b) {
cout << a*b;
//or cout << multiply(a,b);
}
Перша функція поверне ціле значення, яке може використовуватись іншою функцією. Значення повертається і зберігається в пам'яті для використання у разі потреби. Якщо ні, це не видно для людини і просто щасливо сидить у пам’яті.
Друга функція буде виводитись на пристрій виведення за замовчуванням (зазвичай консоль). Значення, повернене оператором множення, передається на вихідний пристрій. Функція multiply_void не повертає фактичне значення.
Оператори самостійно не обов’язково щось повертають. Виклик функції повертає значення. Оператори можуть мати значення. Оператори іноді можуть викликати функції. Приклади включають:
• Оператор виклику функції.
• Перевантажений оператор, який трансформується у виклик функції.
• оператор new, який викликається як частина a виразу new , є викликом функції.
Моя єдина мета згадування викликів функцій - уточнити результат проти повернення. На основі вивчення всіх 126 випадків "повернення" та слів, що походять від нього, у [expr] , розділ, схоже, обережно використовує слово return для посилання на:
• результат виклику функції
• аспекти управління потоком, пов’язані з корутинами
Гаразд, цього достатньо педантизму щодо результату проти повернення.
Оператори C ++ повертають щось чи ні, це залежить від того, як ви ними користувались. Вбудовані оператори C ++ повертають деяке значення до тих пір, доки вони не будуть примусовими для повернення void.