Функция не является однозначной c как исправить

от admin

Как исправить ошибку «cout не является однозначным»?

country::country(char* aname, double at_winter, double at_spring, double at_summer, double at_autumn) :
name(new char[strlen(aname) + 1])
<
strcpy_s(name, strlen(aname) + 1, aname);
t_winter = at_winter;
t_spring = at_spring;
t_summer = at_summer;
t_autumn = at_autumn;
>;

country::country(const country& COUNTRY) :
name(new char[strlen(COUNTRY.name) + 1])
<
strcpy_s(name, strlen(COUNTRY.name) + 1, COUNTRY.name);
t_winter = COUNTRY.t_winter;
t_spring = COUNTRY.t_spring;
t_summer = COUNTRY.t_summer;
t_autumn = COUNTRY.t_autumn;
>;

ostream& operator<<(ostream& Out, const country& COUNTRY)
<
Out << «\nСТРАНА: » << COUNTRY.name << «\nТЕМПЕРАТУРА ЗИМОЙ» << COUNTRY.t_winter << «\nТЕМПЕРАТУРА ВЕСНОЙ» << COUNTRY.t_spring << «\nТЕМПЕРАТУРА ЛЕТОМ» << COUNTRY.t_summer << «\nТЕМПЕРАТУРА ОСЕНЬЮ » << COUNTRY.t_autumn;

istream& operator>>(istream& In, country& COUNTRY)
<
char TEMP[123];
In >> TEMP >> COUNTRY.t_winter >> COUNTRY.t_spring >> COUNTRY.t_summer >> COUNTRY.t_autumn;
delete[] COUNTRY.name;
COUNTRY.name = new char[strlen(TEMP) + 1];
strcpy_s(COUNTRY.name, strlen(TEMP) + 1, TEMP);
return In;
>;

country& country::operator=(const country& COUNTRY) <
if (this == &COUNTRY) return *this;
delete[] name;
name = new char[strlen(COUNTRY.name) + 1];
strcpy_s(name, strlen(COUNTRY.name) + 1, COUNTRY.name);
name = COUNTRY.name;
t_winter = COUNTRY.t_winter;
t_spring = COUNTRY.t_spring;
t_summer = COUNTRY.t_summer;
t_autumn = COUNTRY.t_autumn;
return *this;
>;

NewCountry::NewCountry() :
country()
<
polusharie = NULL;
>;

NewCountry::NewCountry(char* aname, double at_winter, double at_spring, double at_summer, double at_autumn, int apolusharie) :
country(aname,at_winter, at_spring, at_summer, at_autumn)
<
polusharie = apolusharie;
>;

NewCountry::NewCountry(const NewCountry& COUNTRY) :
country(COUNTRY)
<
polusharie = COUNTRY.polusharie;
>;

string NewCountry::sReturnpolusharie() <
if (polusharie == 1) return «северное»;
if (polusharie == 2) return «южное»;
if (polusharie == 3) return «по обе стороны экватора»;
return «. ОШИБКА:данные отсутствуют. «;
>;

ostream& operator<<(ostream& Out, const NewCountry& COUNTRY)
<
Out << «\nСТРАНА: » << COUNTRY.name << «\nТЕМПЕРАТУРА ЗИМОЙ» << COUNTRY.t_winter << «\nТЕМПЕРАТУРА ВЕСНОЙ» << COUNTRY.t_spring << «\nТЕМПЕРАТУРА ЛЕТОМ» << COUNTRY.t_summer << «\nТЕМПЕРАТУРА ОСЕНЬЮ » << COUNTRY.t_autumn;
Out << «\nРАСПОЛОЖЕНИЕ ОТНОСИТЕЛЬНО ЭКВАТОРА: «;
if (COUNTRY.polusharie == 1) Out << «СЕВЕРНОЕ»;
if (COUNTRY.polusharie == 2) Out << «ЮЖНОЕ»;
if (COUNTRY.polusharie == 3) Out << «ПО ОБЕ СТОРОНЫ ЭКВАТОРА»;
return Out;
>;

istream& operator>>(istream& In, NewCountry& COUNTRY)
<
char TEMP[123];
In >> TEMP >> COUNTRY.t_winter >> COUNTRY.t_spring >> COUNTRY.t_summer >> COUNTRY.t_autumn >> COUNTRY.polusharie;
delete[] COUNTRY.name;
COUNTRY.name = new char[strlen(TEMP) + 1];
strcpy_s(COUNTRY.name, strlen(TEMP) + 1, TEMP);
return In;
>;

NewCountry& NewCountry::operator=(const NewCountry& COUNTRY) <
if (this == &COUNTRY) return *this;
delete[] name;
name = new char[strlen(COUNTRY.name) + 1];
strcpy_s(name, strlen(COUNTRY.name) + 1, COUNTRY.name);
t_winter = COUNTRY.t_winter;
t_spring = COUNTRY.t_spring;
t_summer = COUNTRY.t_summer;
t_autumn = COUNTRY.t_autumn;
polusharie = COUNTRY.polusharie;
return *this;
>;

void main() <
setlocale(LC_ALL, «Russian»);
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
int N;
double winter = lol[0].ReturnT_Winter;
double summer = lol[0].ReturnT_Summer;
NewCountry* lol;
cout << «КОЛИЧЕСТВО СТРАН: «;
cin >> N;
lol = new NewCountry[N];
cout << «Введите данные\nНазвание страны , температура зимой,весной и летом, в каком полушарии находится (1 — северное, 2 — южное, 3 — по обе стороны экватора ):\n\n»;
for ( int i = 0; i < N; i++) cin >> lol[i];
for ( int i = 0; i < N; i++)
<
if (winter < lol[i].ReturnT_Winter())
winter = lol[i].ReturnT_Winter();
if (summer > lol[i].ReturnT_Summer ())
summer = lol[i].ReturnT_Summer();
>
>;
cout << «\nПроверка оператора =\n»;
lol[0] = lol[1];
cout << lol[0] << endl;
cout << lol[1] << endl;
cout << «\nПроверка конструктора копирования\n»;
NewCountry Copy(lol[2]);
cout << Copy << endl;
cout << lol[2] << endl;
delete[] lol;
system(«pause»);
>;

Функция не является однозначной c как исправить

I was working with a custom iOS framework project in Xcode.There I am getting a lot of errors mentioning «Reference to ‘ ‘ is ambigous».I am attaching the screenshot of errors.Please help me correcting this.

It looks like you forgot to mention any «;» or «,» in the code line. or i can’t debug that’s why it looks like problem with if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) line. – Code Hunterr 06 июл. 15 2015-07-06 04:31:41

Click on the disclosure next to the error (in the Error navigator on the left). Make the navigator wide enough to show the full messages after you do. Post a screenshot of those messages. – rob mayoff 06 июл. 15 2015-07-06 04:52:40

@robmayoff:Yes please check the screen shot – haritha 06 июл. 15 2015-07-06 05:09:26

Actually when I build this in latest iOS 8 sdks I am not getting any error.It is showing problems in sdks 6.1 and other lower versions.But I want to run this in sdks 6.1 itself – haritha 06 июл. 15 2015-07-06 05:12:53

Actually This error was cleared when I shift from iOS SDK 6.1 to 7.1(or any version higher that 6.1)

i am having same ios SDK. and i import UIKit and CoreGraphicsframework the error is shown CGRectMinXEdge is ambiguous in MMDrawer class. what can i do? – ios developer 20 июл. 16 2016-07-20 13:09:09

The error message makes me think you have two declarations of the same library functions. All of those references are from UIKit . Check to make sure only one version of UIKit is referenced in your project (check the frameworks), and make sure any libraries you have included are linking the same UIKit version as the rest of the app.

Steps to fix from here:

  • Clean the project
  • Delete everything inside ‘

Adding more information to Jason’s answer.

The error message makes me think you have two declarations of the same library functions. All of those references are from UIKit

mostly this can be occurring because of the header files. As you can see all the errors indicates that it is quoting the enum values. Enum values will always be in the .h files. Normally the reference headers(.h files) will be present inside the frameworks. It is a common mistake that sometimes these header files will be buried some where in our code by any third party frameworks. So kindly check your third party libraries.

I did face this issue once and after searching everywhere i could not able to find the solution. The only thing solved my issue was

Opening a fresh project and importing my files into that project. Actually it really took me less than 10 minutes to move to a new project and immediately my xcode was happy. This is definitely worth a try.

Why is this bug and your solution related to namespaces? – Amin Negm-Awad 08 июл. 15 2015-07-08 05:33:38

Clean your project and rebuild again.If it don’t work then create a new project

Set value of Enable Module (C and objective-c) to No

This doesn’t solve the problem. – Aanchal Chaurasia 27 окт. 17 2017-10-27 11:55:51

country::country(char* aname, double at_winter, double at_spring, double at_summer, double at_autumn) :
name(new char[strlen(aname) + 1])
strcpy_s(name, strlen(aname) + 1, aname);
t_winter = at_winter;
t_spring = at_spring;
t_summer = at_summer;
t_autumn = at_autumn;
>;

country::country(const country& COUNTRY) :
name(new char[strlen(COUNTRY.name) + 1])
strcpy_s(name, strlen(COUNTRY.name) + 1, COUNTRY.name);
t_winter = COUNTRY.t_winter;
t_spring = COUNTRY.t_spring;
t_summer = COUNTRY.t_summer;
t_autumn = COUNTRY.t_autumn;
>;

istream& operator>>(istream& In, country& COUNTRY)
char TEMP[123];
In >> TEMP >> COUNTRY.t_winter >> COUNTRY.t_spring >> COUNTRY.t_summer >> COUNTRY.t_autumn;
delete[] COUNTRY.name;
COUNTRY.name = new char[strlen(TEMP) + 1];
strcpy_s(COUNTRY.name, strlen(TEMP) + 1, TEMP);
return In;
>;

country& country::operator=(const country& COUNTRY) if (this == &COUNTRY) return *this;
delete[] name;
name = new char[strlen(COUNTRY.name) + 1];
strcpy_s(name, strlen(COUNTRY.name) + 1, COUNTRY.name);
name = COUNTRY.name;
t_winter = COUNTRY.t_winter;
t_spring = COUNTRY.t_spring;
t_summer = COUNTRY.t_summer;
t_autumn = COUNTRY.t_autumn;
return *this;
>;

NewCountry::NewCountry() :
country()
polusharie = NULL;
>;

NewCountry::NewCountry(char* aname, double at_winter, double at_spring, double at_summer, double at_autumn, int apolusharie) :
country(aname,at_winter, at_spring, at_summer, at_autumn)
polusharie = apolusharie;
>;

8.11 – Разрешение перегрузки функций и неоднозначные совпадения

В предыдущем уроке («8.10 – Различение перегруженных функций») мы обсудили, какие атрибуты функции используются для различения перегруженных функций друг от друга. Если перегруженная функция не отличается должным образом от других перегрузок с тем же именем, компилятор выдаст ошибку компиляции.

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

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

В простых случаях, когда тип аргументов функции и тип параметров функции точно совпадают, это (обычно) просто:

Но что происходит в случаях, когда типы аргументов в вызове функции не совсем соответствуют типам параметров ни в одной из перегруженных функций? Например:

Тот факт, что здесь нет точного совпадения, не означает, что соответствие не может быть найдено – в конце концов, тип char или long можно неявно преобразовать в int или double . Но какое преобразование лучше всего выполнить в каждом конкретном случае?

В этом уроке мы исследуем, как компилятор сопоставляет заданный вызов функции с конкретной перегруженной функцией.

Разрешение вызовов перегруженных функций

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

На каждом шаге в вызове функции компилятор применяет к аргументу(ам) кучу различных преобразований типов. Для каждого примененного преобразования компилятор проверяет, соответствует ли какая-либо из перегруженных функций. После того, как все преобразования различных типов были применены и проверены на совпадения, этап завершен. Результатом будет один из трех возможных исходов:

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

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

Последовательность сопоставления аргументов

Шаг 1) Компилятор пытается найти точное совпадение. Это происходит в два этапа. Во-первых, компилятор смотрит, существует ли перегруженная функция, в которой тип аргументов в вызове функции точно соответствует типу параметров в перегруженных функциях. Например:

Читать:
Как через командную строку посмотреть диски

Поскольку 0 в вызове функции print(0) является int , компилятор будет проверять, была ли объявлена перегрузка print(int) . Поскольку это так, компилятор определяет, что print(int) является точным совпадением.

Во-вторых, компилятор применит ряд тривиальных преобразований к аргументам в вызове функции. Тривиальные преобразования – это набор определенных правил преобразования, которые изменяют типы (без изменения значения) с целью поиска совпадения. Например, неконстантный тип можно тривиально преобразовать в константный тип:

В приведенном выше примере мы вызвали print(x) , где x – это число int . Компилятор тривиально преобразует x из int в const int , который затем соответствует print(const int) .

Для продвинутых читателей

Преобразование не ссылочного типа в ссылочный тип (или наоборот) также является тривиальным преобразованием).

Совпадения, полученные с помощью тривиальных преобразований, считаются точными совпадениями.

Шаг 2) Если точное совпадение не найдено, компилятор пытается найти совпадение, применяя к аргументу(ам) числовое продвижение. В уроке «8.2 – Продвижение целочисленных типов и типов с плавающей запятой» мы рассмотрели, как некоторые узкие целочисленные типы и типы с плавающей запятой могут автоматически преобразовываться в более широкие типы, такие как int или double . Если после числового продвижения совпадение найдено, вызов функции разрешен.

Для print('a') , поскольку точное совпадение для print(char) не может быть найдено на предыдущем шаге, компилятор преобразует char ' a ' в int и ищет совпадение. Это соответствует print(int) , поэтому вызов функции разрешается как print(int) .

Шаг 3) Если совпадение не найдено с помощью числового продвижения, компилятор пытается найти совпадение, применяя к аргументам числовые преобразования (8.3 – Числовые преобразования).

В этом случае, поскольку нет print(char) (точное совпадение) и print(int) (совпадение при числовом продвижении), ' a ' численно преобразуется в double и сопоставляется с print(double) .

Ключевые выводы

Совпадения, полученные с помощью числовых продвижений (расширяющих преобразований), имеют приоритет над любыми совпадениями, полученными с помощью числовых преобразований.

Шаг 4) Если совпадение не найдено с помощью числового преобразования, компилятор пытается найти совпадение с помощью любых пользовательских преобразований. Хотя мы еще не рассмотрели пользовательские преобразования, некоторые типы (например, классы) могут определять преобразования в другие типы, которые могут быть вызваны неявно. Вот пример, чтобы проиллюстрировать суть:

В этом примере компилятор сначала проверит, существует ли точное совпадение с print(X) . Мы не определили такой функции. Затем компилятор проверит, можно ли применить к x числовое продвижение, чего он не может. Затем компилятор проверит, можно ли применить к x числовое преобразование, чего он также не может. Наконец, компилятор будет искать любые пользовательские преобразования. Поскольку мы определили пользовательское преобразование из X в int , компилятор преобразует X в int , чтобы соответствовать print(int) .

Связанный контент

Мы обсудим, как создавать пользовательские преобразования для типов классов (путем перегрузки операторов преобразования типов) в уроке «13.11 – Перегрузка операторов преобразования типов данных».

Шаг 5) Если совпадение не найдено с помощью пользовательского преобразования, компилятор будет искать соответствующую функцию, которая использует многоточие.

Связанный контент

Шаг 6) Если к этому моменту совпадений не найдено, компилятор сдается и выдает ошибку компиляции о невозможности найти подходящую функцию.

Неоднозначные совпадения

С неперегруженными функциями каждый вызов функции либо будет преобразован в функцию, либо совпадение не будет найдено, и компилятор выдаст ошибку компиляции:

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

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

Поскольку литерал 5l имеет тип long , компилятор сначала проверяет, может ли он найти точное совпадение для print(long) , но не найдет его. Затем компилятор попробует выполнить числовое продвижение, но значения типа long не могут быть расширены, поэтому здесь тоже нет совпадений.

После этого компилятор попытается найти совпадение, применив числовые преобразования к аргументу long . В процессе проверки всех правил преобразования чисел компилятор найдет два возможных совпадения. Если аргумент long численно преобразован в int , тогда вызов функции будет соответствовать print(int) . Если вместо этого аргумент long преобразуется в double , тогда он будет соответствовать print(double) . Поскольку посредством числового преобразования были обнаружены два возможных совпадения, вызов функции считается неоднозначным.

В Visual Studio 2019 это приводит к следующему сообщению об ошибке:

Ключевые выводы

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

Вот еще один пример, который дает неоднозначные совпадения:

Хотя вы можете ожидать, что 0 приведет к print(unsigned int) , и 3.14159 приведет к print(float) , оба этих вызова приводят к неоднозначному совпадению. Значение 0 типа int может быть численно преобразовано в unsigned int или float , поэтому обе перегрузки соответствуют одинаково хорошо, и результатом является неоднозначный вызов функции.

То же самое относится к преобразованию числа типа double в тип float или unsigned int . Оба являются числовыми преобразованиями, поэтому обе перегрузки соответствуют одинаково, и результат снова неоднозначен.

Разрешение неоднозначных совпадений

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

  1. Часто лучший способ – просто определить новую перегруженную функцию, которая принимает параметры именно того типа, с которым вы пытаетесь ее вызвать. Тогда C++ сможет найти точное совпадение для вызова функции.
  2. В качестве альтернативы явно приведите неоднозначные аргументы к типу функции, которую хотите вызвать. Например, чтобы print(0) вызывал print(unsigned int) , вы должны сделать это:
  3. Если ваш аргумент является литералом, вы можете использовать суффикс литерала, чтобы убедиться, что ваш литерал интерпретируется как правильный тип:

Список наиболее часто используемых суффиксов можно найти в уроке «4.13 – Литералы».

Сопоставление функций с несколькими аргументами

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

В случае, если такая функция будет найдена, это явный и однозначно лучший выбор. Если такая функция не найдена, вызов будет считаться неоднозначным (или без совпадений).

В приведенной выше программе все функции точно соответствуют по первому аргументу. Однако верхняя функция соответствует по второму параметру через числовое продвижение, тогда как другие функции требуют числового преобразования. Таким образом, print(char, int) однозначно является лучшим совпадением.

Урок №108. Обработка ошибок, cerr и exit()

При написании программ возникновение ошибок почти неизбежно. Ошибки в языке C++ делятся на две категории: синтаксические и семантические.

Синтаксические ошибки

Синтаксическая ошибка возникает при нарушении правил грамматики языка C++. Например:

если 7 не равно 8, то пишем «not equal»;

Хотя этот стейтмент нам (людям) понятен, компьютер не сможет его корректно обработать. В соответствии с правилами грамматики языка C++, корректно будет:

Синтаксические ошибки почти всегда улавливаются компилятором и их обычно легко исправить. Следовательно, о них слишком беспокоиться не стоит.

Семантические ошибки

Семантическая (или «смысловая») ошибка возникает, когда код синтаксически правильный, но выполняет не то, что нужно программисту. Например:

Возможно, программист хотел, чтобы вывелось 0 1 2 3 , но на самом деле выведется 0 1 2 3 4 .

Семантические ошибки не улавливаются компилятором и могут иметь разное влияние: некоторые могут вообще не отображаться, что приведет к неверным результатам, к повреждению данных или вообще к сбою программы. Поэтому о семантических ошибках беспокоиться уже придется.

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

Что произойдет, если x будет равен 4 ? Условие выполнится как true , а программа выведет x is greater than 4 . Логические ошибки иногда бывает довольно-таки трудно обнаружить.

Другой распространенной семантической ошибкой является ложное предположение. Ложное предположение возникает, когда программист предполагает, что что-то будет истинным или ложным, а оказывается наоборот. Например:

Заметили потенциальную проблему здесь? Предполагается, что пользователь введет значение между 0 и длиной строки Hello, world! . Если же пользователь введет отрицательное число или число, которое больше длины указанной строки, то index окажется за пределами диапазона массива. В этом случае, поскольку мы просто выводим значение по индексу, результатом будет вывод мусора (при условии, что пользователь введет число вне диапазона). Но в других случаях ложное предположение может привести и к изменениям значений переменных, и к сбою в программе.

Безопасное программирование — это методика разработки программ, которая включает анализ областей, где могут быть допущены ложные предположения, и написание кода, который обнаруживает и обрабатывает любой случай такого нарушения, чтобы свести к минимуму риск возникновения сбоя или повреждения программы.

Определение ложных предположений

Оказывается, мы можем найти почти все предположения, которые необходимо проверить в одном из следующих трех мест:

При вызове функции, когда caller может передать некорректные или семантически бессмысленные аргументы.

При возврате значения функцией, когда возвращаемое значение может быть индикатором выполнения (произошла ли ошибка или нет).

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

Поэтому, придерживаясь безопасного программирования, нужно следовать следующим 3-м правилам:

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

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

Проверяйте данные ввода на соответствие ожидаемому типу данных и его диапазону.

Рассмотрим примеры проблем:

Проблема №1: При вызове функции caller может передать некорректные или семантически бессмысленные аргументы:

Related Posts