Call of overloaded abs double is ambiguous что за ошибка

Добавил пользователь Евгений Кузнецов
Обновлено: 19.09.2024

Только начал программировать. Пока написал только вот это.

Компилятор указывает на строку Serial.write и пишет "call of overloaded 'write(word&, int)' is ambiguous".

Если убрать из скобок размер массива, и написать Serial.write(Inputs[0]); то компилятор это съедает. Но хотелось бы понять как передавать массив байтов.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

for (byte i = 0; i

А чтобы понять, надо почитать описание Serial.write.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Вы предлагаете передавать данные побайтно?

" Данные послаются как один или серия байтов "

Мне нужно послать все данные массива, т.е. как серию байтов.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

а они внутри функции всё равно побайтно передадутся. так что это полный аналог. но если очень хочется так, то вот так.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Пишет no matching function for call to 'HardwareSerial::write(word*, int)'

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

ЕвгенийП аватар

Пишет no matching function for call to 'HardwareSerial::write(word*, int)'

Ну и правильно пишет. Если у Вас массив байтов, так нафига Вы его обозвали word в 6-ой строке? Пишите byte

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Обозвал. Снова пишет "call of overloaded 'write(byte&, byte&)' is ambiguous"

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

та итить колотить, поставтье наконец-то & перед Inputs.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Я поставил задержку 100мс чтобы было видно мигание светодиода (иначе он просто горит при постоянной передаче, и не понятно передаются данные или нет).

Не могу понять- почему данные шлются сразу в UART и USB? Видно мигание светодиода подключённого к TX, и также на монитор порта приходят последовательности байт.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Превращение значения в адрес, где оно хранится. Inputs -- массив, то бишь адрес начала хранения теперь байтиков в количестве 8 шт. Квадратные скобки и чиселко в них: [0] -- указание взять ЗНАЧЕНИЕ, лежащее в нулевом байтике от начала (адреса) "Inputs". А Вам надо передать в функцию не значение а адрес .. вот унарная операция & и возвращает адрес места хранения указанного значения. Правильно прочитав вышеизложенное, можно поступать "двояко":

1. Serial .write(&(Inputs[0]), x); -- получить адрес элемента массива (не обязательно 0..)

2. Serial .write(Inputs, x); -- сам Inputs является адресом нулевого элемента массива (но только 0)..

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Нашел Вашу тему.

Помогите разрешить проблему. Задача в следующем, необходимо передать значение температуры (float с 2-мя знаками после запятой) с одной ардуины на другую по UART, получается какая-то "чушь". При передаче в Serial.write значения температуры пишет, что тип float, не может передаваться. Float умножаю на 100 Перевожу в тип int (т.е 2 байта)получаю 4-х значное число, отсылаю Serial.write, на приемной стороне не получаю полную чушь. Методом проб и ошибок "вкурил", что у меня принимается только 1 байт, причем последний. Подскажите как передавать и соответственно получать через UART больше 1-го байта.

В качестве кандидатов предлагает эти мои две метода.
Я не понял, что ему не ясно? Второй параметр шаблона - число (а не булево значение). Значит все должно определяться однозначно.

Удалить второй метод и записать первый с uint8_t count = sizeof(T) не очень хотелось бы.

Ambiguous call to overloaded function
При использовании sqrt (да и других мат. функций(sin, cos, pow. ) ) выдает ошибку, где говорится о.

Error: call of overloaded ‘Function’ is ambiguous
log.cpp:166:25: error: call of overloaded ‘localtime_r(time_t*, tm*)’ is ambiguous log.cpp:166:25.

'sqrt' : ambiguous call to overloaded function
здраствуйте! ошибка в заголовке. Чё то я запамятовал как указать компилятору какую именно версию.


Ambiguous call to overloaded function / рекурсивная функция
Функция должна вызываться из движка на удаление связных списков. dellTree(Aster::tree); Далее она.

работает, правда не знаю как грамотно в forward эти auto&& засунуть при передаче во второй функции:

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

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

косяк же приключился потому,
что значение интегральной константы 3U может кастиццо и в int8_t, и в bool.
компилятор как бы не телепат, во что именно предполагается каст.

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

кастую DrOffset в тред

Решение

Я не понял, что ему не ясно? Второй параметр шаблона - число (а не булево значение). Значит все должно определяться однозначно.

В С++ выбор лучшей функции-кандидата в процессе overload resolution выполняется только на основе того, как хорошо типы аргументов функции соответствуют типам параметров функции.

Насколько же хорошо типы нетиповых (non-type) аргументов шаблона соответствуют типам нетиповых параметров шаблона значения не имеет и никогда не имело. И на overload resolution это никакого влияния не оказывает. В С++ нет механизма "предпочтения" тех или иных версий перегруженного шаблона на основе того, как "хорошо" совпадали типы шаблонных аргументов. Компилятор интересует лишь то, является ли аргумент допустимым для данного параметра.

Все, что компилятор должен сделать - это нагенерировать из ваших шаблонов набор функций-кандидатов, к которым потом будет применяться overload resolution. Все что для этого надо - это чтобы шаблон функции успешно специализировался. Если нетиповой параметр шаблона является целочисленным значением, то любой целочисленный аргумент, который не требует сужающего преобразования (narrowing conversion) является допустимым аргументом шаблона. Так как преобразование unsigned -> bool формально не является сужающим, ваш второй шаблон тоже успешно включается в рассмотрение.

Я бы даже сказал, что существует больше риска того, что ваш первый шаблон будет исключен из рассмотрения, ибо преобразование unsigned -> uint8_t в общем случае может быть сужающим. Но для явной константы 3U сужения нет, поэтому первый шаблон был допущен к рассмотрению.

Но это еще пол-дела. Даже если бы в С++ существовал некий механизм мета-overload resolution, рассматривающий на нетиповые параметрах шаблонов, у вас бы все равно сохранилась неоднозначность. Точного соответствия-то у вас нет. Для первого шаблона требуется преобразование unsigned -> uint8_t , а для второго unsigned -> bool . Эти преобразования обладают одинаковым рангом и приводят к неоднозначности, как в таком простом примере

The cplusplus page you cite does not say to include cmath.h. It says cmath. That's the C++ version of math.h. Don't include both.

4 Answers 4

The header is a C std lib header. It defines a lot of stuff in the global namespace. The header is the C++ version of that header. It defines essentially the same stuff in namespace std . (There are some differences, like that the C++ version comes with overloads of some functions, but that doesn't matter.) The header doesn't exist.

Since vendors don't want to maintain two versions of what is essentially the same header, they came up with different possibilities to have only one of them behind the scenes. Often, that's the C header (since a C++ compiler is able to parse that, while the opposite won't work), and the C++ header just includes that and pulls everything into namespace std . Or there's some macro magic for parsing the same header with or without namespace std wrapped around it or not. To this add that in some environments it's awkward if headers don't have a file extension (like editors failing to highlight the code etc.). So some vendors would have be a one-liner including some other header with a .h extension. Or some would map all includes matching to (which, through macro magic, becomes the C++ header when __cplusplus is defined, and otherwise becomes the C header) or or whatever.

That's the reason why on some platforms including things like , which ought not to exist, will initially succeed, although it might make the compiler fail spectacularly later on.

I have no idea which std lib implementation you use. I suppose it's the one that comes with GCC, but this I don't know, so I cannot explain exactly what happened in your case. But it's certainly a mix of one of the above vendor-specific hacks and you including a header you ought not to have included yourself. Maybe it's the one where maps to with a specific (set of) macro(s) which you hadn't defined, so that you ended up with both definitions.

Note, however, that this code still ought not to compile:

There shouldn't be an abs() in the global namespace (it's std::abs() ). However, as per the above described implementation tricks, there might well be. Porting such code later (or just trying to compile it with your vendor's next version which doesn't allow this) can be very tedious, so you should keep an eye on this.

Информация о компиляторе (не уверен, имеет ли это значение):

задан 03 сен '09, 12:09

На странице cplusplus, которую вы цитируете, не говорится о включении cmath.h. Там написано cmath. Это версия math.h для C ++. Не включайте оба. - Rob Kennedy

4 ответы

Заголовок является заголовком библиотеки C std. Он определяет множество вещей в глобальном пространстве имен. Заголовок - это версия этого заголовка для C ++. Он определяет, по сути, то же самое в пространстве имен std . (Есть некоторые отличия, например, версия для C ++ поставляется с перегрузками некоторых функций, но это не имеет значения.) Заголовок не существует.

Поскольку производители не хотят поддерживать две версии того, что по сути является одним и тем же заголовком, они придумали разные возможности иметь только одну из них за кулисами. Часто это заголовок C (поскольку компилятор C ++ может его анализировать, а обратное не работает), а заголовок C ++ просто включает его и переносит все в пространство имен. std . Или есть магия макросов для разбора одного и того же заголовка с или без namespace std обернут или нет. К этому добавьте, что в некоторых средах неудобно, если заголовки не имеют расширения файла (например, редакторы не могут выделить код и т. Д.). Таким образом, некоторые поставщики быть однострочным, включая другой заголовок с .h расширение. Или некоторые будут отображать все, включая соответствие в (который с помощью макро-магии становится заголовком C ++, когда __cplusplus определен, и в противном случае становится заголовком C) или или что-то еще.

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

Я понятия не имею, какую реализацию std lib вы используете. Я полагаю, что это тот, который поставляется с GCC, но этого я не знаю, поэтому я не могу точно объяснить, что произошло в вашем случае. Но это, безусловно, смесь одного из вышеупомянутых хаков, связанных с конкретными поставщиками, и вы включаете заголовок, который вам не следовало включать. Может это тот, где карты для с конкретным (набором) макросов, которые вы не определили, так что вы получили оба определения.

Обратите внимание, однако, что этот код по-прежнему не должен компилироваться:

Не должно быть abs() в глобальном пространстве имен (это std::abs() ). Однако, согласно описанным выше уловкам реализации, вполне может быть. Перенос такого кода позже (или просто попытка скомпилировать его со следующей версией вашего поставщика, которая не позволяет этого) может быть очень утомительно, поэтому вы должны следить за этим.

ответ дан 31 мар '14, в 18:03

Все сводится к следующему: math.h от C и был создан более 10 лет назад. В math.h из-за своей примитивной природы abs() функция "по существу" предназначена только для целочисленных типов, и если вы хотите получить абсолютное значение двойного числа, вам нужно было использовать fabs() . Когда был создан C ++, потребовалось math.h и сделал это cmath . cmath по сути является math.h, но улучшен для C ++. Это улучшило такие вещи, как необходимость различать fabs() и пресс, и просто сделал abs() как для двойных, так и для целочисленных типов. В итоге: используйте math.h и используйте abs() для целых чисел, fabs() для парного разряда или используйте cmath и просто используйте пресс для всего (проще и рекомендуется)

Надеюсь, это поможет любому, у кого такая же проблема!

Используйте fabs () вместо abs (), это то же самое, но для чисел с плавающей запятой вместо целых.

это не совсем верно в std пространство имен, где abs это перегрузка для float , double так далее. - Флексографская ♦

исправлена ​​ошибка gcc6: вызов перегруженного abs (uint32_t) неоднозначен - Sergio

@ Sérgio Я думаю, вам следует просто удалить вызов abs, поскольку uint32_t беззнаковый. (Вместо этого вы неявно приводите uint32_t к удвоению для fabs (double), а затем я предполагаю вернуть результат к целому числу!) - Raptor007

Я не помню, где я использовал этот патч, я тоже не могу найти где, я смотрел в google, но я согласен с вами . Я хотел бы просмотреть это исправление gcc6 Спасибо. - Sergio

Заголовок является заголовком C std lib. Он определяет много вещей в глобальном пространстве имен. Заголовок - это С++-версия этого заголовка. Он определяет по существу тот же самый материал в пространстве имен std . (Есть некоторые отличия, например, версия С++ поставляется с перегрузками некоторых функций, но это не имеет значения.) Заголовок не существует.

Поскольку поставщики не хотят поддерживать две версии того, что по сути является одним и тем же заголовком, они придумали разные возможности, чтобы иметь только одну из них за кулисами. Часто, что заголовок C (поскольку компилятор С++ способен разобрать это, в то время как противоположное не будет работать), а заголовок С++ включает это и вытаскивает все в пространство имен std . Или есть макрос магии для разбора одного и того же заголовка с или без namespace std , обернутых вокруг него или нет. Для этого добавьте, что в некоторых средах это неудобно, если заголовки не имеют расширения файла (например, редакторы не могут выделить код и т.д.). Таким образом, некоторые поставщики имели бы как однострочный, включая другой заголовок с расширением .h . Или некоторые из них будут отображать все, включая сопоставление с (которое с помощью макроса становится заголовком С++, когда __cplusplus определено и в противном случае становится заголовком C) или или что-то еще.

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

Я не знаю, какую версию std lib вы используете. Я предполагаю, что это тот, который поставляется с GCC, но этого я не знаю, поэтому я не могу точно объяснить, что произошло в вашем случае. Но это, безусловно, сочетание одного из вышеупомянутых хакеров, связанных с продавцом, и вы включаете заголовок, который вы не должны были включать в себя. Возможно, это тот, где отображается на с определенным (набором) макросов, которые вы не определили, так что вы оказались с обоими определениями.

Обратите внимание, что этот код еще не должен компилироваться:

В глобальном пространстве имен не должно быть abs() (it std::abs() ). Однако в соответствии с описанными выше трюками реализации вполне может быть. Портирование такого кода позже (или просто попытка скомпилировать его с вашей следующей версией поставщика, что не позволяет этого) может быть очень утомительным, поэтому вам следует следить за этим.

Ответ 2

Это сводится к следующему: math.h от C и был создан более 10 лет назад. В math.h из-за его примитивного характера функция abs() "по существу" предназначена только для целых типов, и если вы хотите получить абсолютное значение double, вам нужно использовать fabs() . Когда С++ был создан, он принял math.h и сделал его cmath . cmath по существу является math.h, но улучшен для С++. Он улучшил такие вещи, как необходимость различать fabs() и abs, и только что сделал abs() для обоих типов double и integer. В итоге: Используйте math.h и используйте abs() для целых чисел, fabs() для парных или использовать cmath и просто абс для всего (проще и рекомендуется)

Надеюсь, это поможет любому, у кого такая же проблема!

Ответ 3

Используйте fabs() вместо abs(), это то же самое, но для float вместо целых чисел.

Ответ 4

В моих случаях я решил эту проблему при использовании labs() вместо abs() .

Читайте также: