Отсутствует оператор соответствующий этим операндам c string

Отсутствует оператор соответствующий этим операндам c string

using namespace std;

int S(int Length, int Wingth)

return (Length * Wingth);

int Per(int Length, int Wingth)

cout >": не найден оператор, принимающий правый операнд типа "overloaded-function" (или приемлемое преобразование отсутствует)

IntelliSense: отсутствует оператор ">>", соответствующий этим операндам

типы операндов: std::basic_istream > >>

Как избавиться от ошибки?

PS. Не судите строго. Программу писал отбалды дабы понять суть операторов. Начал изучать С++

Обновл. 12 Янв 2020 |

C++ не компилирует шаблоны функций напрямую. Вместо этого, когда компилятор встречает вызов шаблона функции, он копирует шаблон функции и заменяет типы параметров шаблона функции фактическими (передаваемыми) типами данных. Функция с фактическими типами данных называется экземпляром шаблона функции (или ещё «объектом шаблона функции»).

Рассмотрим это на практике. Во-первых, создадим шаблон функции:

Затем сделаем вызов шаблона функции:

Компилятор видит, что оба числа являются целочисленными, поэтому он копирует шаблон функции и создаёт экземпляр шаблона max(int, int) :

Это теперь уже «обычная функция». Допустим, что нам снова нужно вызвать max(), но уже с другим типом данных:

C++ автоматически создаёт экземпляр шаблона max(double, double) :

И затем компилирует его. Также стоит отметить, что, если вы создадите шаблон функции, но не вызовете его, то экземпляры этого шаблона созданы не будут.

Операторы, вызовы функций и шаблоны функций

Шаблоны функций работают как с фундаментальными типами данных (char, int, double и т.д.), так и с классами (но с нюансом). Экземпляр шаблона компилируется как обычная функция. В обычной функции любые операторы или вызовы других функций, которые используются в этой функции, должны быть определены/перегружены или вы получите ошибку компиляции. Аналогично, любые операторы или вызовы других функций, которые присутствуют в шаблоне функции, должны быть определены/перегружены для работы с фактическими (передаваемыми) типами данных. Рассмотрим это на практике.

Во-первых, создадим простой класс:

Теперь посмотрим, что произойдёт при попытке вызова функции max() с объектами класса Dollars:

C++ создаст следующий экземпляр шаблона функции max():

А затем компилятор попытается скомпилировать эту функцию, но ничего не получится, так как C++ не имеет понятия, как обрабатывать выражение a > b ! Следовательно, это приведёт к ошибке:

Ошибка C2676 бинарный ">": "const T" не определяет этот оператор или преобразование к типу приемлемо к встроенному оператору

Сообщение об ошибке указывает на тот факт, что мы не перегрузили оператор > для класса Dollars. Давайте перегрузим:

Теперь C++ знает, как обрабатывать выражение a > b , когда в качестве переменных используются объекты класса Dollars!

Ещё один пример

Создадим шаблон функции, которая вычисляет среднее арифметическое элементов массива:

Как вы видите, всё отлично работает с фундаментальными типами данных!

Поскольку тип возврата шаблона функции тот же, что и тип передаваемых элементов массива в функцию, то вычисление среднего арифметического целочисленных значений приведёт к целочисленному результату (с отбрасыванием любой дробной части), как и вычисление значений типа double приведёт к результату типа double. Это может быть не очевидным, поэтому хорошим тоном будет указать это в комментариях.

Читайте также:  Как установить lmod на samsung

Теперь посмотрим, что произойдёт при вызове функции average() с объектами класса Dollars:

1>c:userskiclisource
eposconsoleapplication10consoleapplication10consoleapplication10.cpp(37): error C2679: бинарный " with
1> [
1> T=Dollars
1> ]
1>c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(508): note: может быть "std::basic_ostream &std::basic_ostream ::operator *)"
1>c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(480): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(460): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(440): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(420): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(400): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(380): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(360): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(340): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(320): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(295): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(275): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(241): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(221): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(215): note: или "std::basic_ostream &std::basic_ostream ::operator c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(209): note: или "std::basic_ostream &std::basic_ostream ::operator &(__cdecl *)(std::basic_ios &))"
1>c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(204): note: или "std::basic_ostream &std::basic_ostream ::operator &(__cdecl *)(std::basic_ostream &))"
1>c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(702): note: или "std::basic_ostream &std::operator (std::basic_ostream &,const char *)"
1>c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(749): note: или "std::basic_ostream &std::operator (std::basic_ostream &,char)"
1>c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(787): note: или "std::basic_ostream &std::operator (std::basic_ostream &,const char *)"
1>c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(834): note: или "std::basic_ostream &std::operator (std::basic_ostream &,char)"
1>c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(960): note: или "std::basic_ostream &std::operator (std::basic_ostream &,const signed char *)"
1>c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(967): note: или "std::basic_ostream &std::operator (std::basic_ostream &,signed char)"
1>c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(974): note: или "std::basic_ostream &std::operator (std::basic_ostream &,const unsigned char *)"
1>c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(981): note: или "std::basic_ostream &std::operator (std::basic_ostream &,unsigned char)"
1>c:program files (x86)microsoft visual studio2017communityvc oolsmsvc14.15.26726includeostream(1047): note: или "std::basic_ostream &std::operator (std::basic_ostream &,const std::error_code &)"
1>c:userskiclisource
eposconsoleapplication10consoleapplication10consoleapplication10.cpp(37): note: при попытке сопоставить список аргументов "(std::ostream, T)"
1> with
1> [
1> T=Dollars
1> ]

Компилятор сошёл с ума. Мы говорили о таких ошибках в предыдущем уроке. Несмотря на столь объёмный «результат», здесь всё довольно просто. В первых строках сообщается, что компилятор не смог найти перегрузку оператора Ошибка E0349 отсутствует оператор "

Помните, что average() возвращает объект класса Dollars, а мы пытаемся этот объект вывести с помощью оператора вывода class Dollars

Если же теперь запустить программу, то получим следующее:

Ошибка C2676 бинарный "+=": "T" не определяет этот оператор или преобразование к типу приемлемо к встроенному оператору
Ошибка C2676 бинарный "/=": "T" не определяет этот оператор или преобразование к типу приемлемо к встроенному оператору

Читайте также:  Системой баг трекинга jira

Эти ошибки были вызваны экземпляром шаблона функции, созданным при вызове average(Dollars*, int) . Помните, что при вызове шаблона функции, компилятор копирует шаблон функции с типами параметров, а затем заменяет типы параметров шаблона на фактические (передаваемые) типы данных. Вот экземпляр шаблона функции average(), где T является классом Dollars:

Доброго времени суток!

Желание написать данную статью появилось после прочтения поста Перегрузка C++ операторов, потому что в нём не были раскрыты многие важные темы.

Самое главное, что необходимо помнить — перегрузка операторов, это всего лишь более удобный способ вызова функций, поэтому не стоит увлекаться перегрузкой операторов. Использовать её следует только тогда, когда это упростит написание кода. Но, не настолько, чтобы это затрудняло чтение. Ведь, как известно, код читается намного чаще, чем пишется. И не забывайте, что вам никогда не дадут перегрузить операторы в тандеме со встроенными типами, возможность перегрузки есть только для пользовательских типов/классов.

Синтаксис перегрузки

Синтаксис перегрузки операторов очень похож на определение функции с именем operator@, где @ — это идентификатор оператора (например +, -, >). Рассмотрим простейший пример:

В данном случае, оператор оформлен как член класса, аргумент определяет значение, находящееся в правой части оператора. Вообще, существует два основных способа перегрузки операторов: глобальные функции, дружественные для класса, или подставляемые функции самого класса. Какой способ, для какого оператора лучше, рассмотрим в конце топика.

В большинстве случаев, операторы (кроме условных) возвращают объект, или ссылку на тип, к которому относятся его аргументы (если типы разные, то вы сами решаете как интерпретировать результат вычисления оператора).

Перегрузка унарных операторов

Рассмотрим примеры перегрузки унарных операторов для определенного выше класса Integer. Заодно определим их в виде дружественных функций и рассмотрим операторы декремента и инкремента:

Теперь вы знаете, как компилятор различает префиксные и постфиксные версии декремента и инкремента. В случае, когда он видит выражение ++i, то вызывается функция operator++(a). Если же он видит i++, то вызывается operator++(a, int). То есть вызывается перегруженная функция operator++, и именно для этого используется фиктивный параметр int в постфиксной версии.

Бинарные операторы

Рассмотрим синтаксис перегрузки бинарных операторов. Перегрузим один оператор, который возвращает l-значение, один условный оператор и один оператор, создающий новое значение (определим их глобально):

Во всех этих примерах операторы перегружаются для одного типа, однако, это необязательно. Можно, к примеру, перегрузить сложение нашего типа Integer и определенного по его подобию Float.

Аргументы и возвращаемые значения

Как можно было заметить, в примерах используются различные способы передачи аргументов в функции и возвращения значений операторов.

  • Если аргумент не изменяется оператором, в случае, например унарного плюса, его нужно передавать как ссылку на константу. Вообще, это справедливо для почти всех арифметических операторов (сложение, вычитание, умножение. )
  • Тип возвращаемого значения зависит от сути оператора. Если оператор должен возвращать новое значение, то необходимо создавать новый объект (как в случае бинарного плюса). Если вы хотите запретить изменение объекта как l-value, то нужно возвращать его константным.
  • Для операторов присваивания необходимо возвращать ссылку на измененный элемент. Также, если вы хотите использовать оператор присваивания в конструкциях вида (x=y).f(), где функция f() вызывается для для переменной x, после присваивания ей y, то не возвращайте ссылку на константу, возвращайте просто ссылку.
  • Логические операторы должны возвращать в худшем случае int, а в лучшем bool.
Читайте также:  Не удалось найти пакет winusb

Оптимизация возвращаемого значения

При создании новых объектов и возвращении их из функции следует использовать запись как для вышеописанного примера оператора бинарного плюса.

Честно говоря, не знаю, какая ситуация актуальна для C++11, все рассуждения далее справедливы для C++98.
На первый взгляд, это похоже на синтаксис создания временного объекта, то есть как будто бы нет разницы между кодом выше и этим:

Но на самом деле, в этом случае произойдет вызов конструктора в первой строке, далее вызов конструктора копирования, который скопирует объект, а далее, при раскрутке стека вызовется деструктор. При использовании первой записи компилятор изначально создаёт объект в памяти, в которую нужно его скопировать, таким образом экономится вызов конструктора копирования и деструктора.

Особые операторы

В C++ есть операторы, обладающие специфическим синтаксисом и способом перегрузки. Например оператор индексирования []. Он всегда определяется как член класса и, так как подразумевается поведение индексируемого объекта как массива, то ему следует возвращать ссылку.

Оператор запятая

В число «особых» операторов входит также оператор запятая. Он вызывается для объектов, рядом с которыми поставлена запятая (но он не вызывается в списках аргументов функций). Придумать осмысленный пример использования этого оператора не так-то просто. Хабраюзер AxisPod в комментариях к предыдущей статье о перегрузке рассказал об одном.

Оператор разыменования указателя

Перегрузка этих операторов может быть оправдана для классов умных указателей. Этот оператор обязательно определяется как функция класса, причём на него накладываются некоторые ограничения: он должен возвращать либо объект (или ссылку), либо указатель, позволяющий обратиться к объекту.

Оператор присваивания

Оператор присваивания обязательно определяется в виде функции класса, потому что он неразрывно связан с объектом, находящимся слева от "=". Определение оператора присваивания в глобальном виде сделало бы возможным переопределение стандартного поведения оператора "=". Пример:

Как можно заметить, в начале функции производится проверка на самоприсваивание. Вообще, в данном случае самоприсваивание безвредно, но ситуация не всегда такая простая. Например, если объект большой, можно потратить много времени на ненужное копирование, или при работе с указателями.

Неперегружаемые операторы

Некоторые операторы в C++ не перегружаются в принципе. По всей видимости, это сделано из соображений безопасности.

  • Оператор выбора члена класса ".".
  • Оператор разыменования указателя на член класса ".*"
  • В С++ отсутствует оператор возведения в степень (как в Fortran) "**".
  • Запрещено определять свои операторы (возможны проблемы с определением приоритетов).
  • Нельзя изменять приоритеты операторов
Ссылка на основную публикацию
Отложенное выключение компьютера windows 10
Завершение работы ПК – задача довольно простая, выполняемая всего в три клика мышкой, но иногда ее требуется отложить на определенное...
Ограничить скорость wifi роутера ростелеком
Как повысить скорость интернета Ростелеком на Windows 7, 10 – вопрос, актуальный для многих пользователей. Если вас не устраивает качество...
Онк 140 ошибка е33
Произвести привязку и настройку прибора по ИМ Неисправна плата индикации Индикаторы « t 0 », « t м », «Рм»,...
Отсутствует оператор соответствующий этим операндам c string
using namespace std; int S(int Length, int Wingth) return (Length * Wingth); int Per(int Length, int Wingth) cout >": не...
Adblock detector