Как диагностировать неоднозначный вызов sqrt (int &) в g ++ 4.3.4 - PullRequest
8 голосов
/ 19 мая 2011

Мой код выглядит следующим образом:

#include <cmath>
#include <iostream>

float foo(float f) {
    std::cout << "float\n";
    return f;
}
double foo(double d) {
    std::cout << "double\n";
    return d;
}

int main() {
    int i = 16;
//  foo(i); // ambiguous call, of course
    return (int) std::sqrt(i);
}

Вызов в последней строке не сообщается неоднозначно даже с -pedantic -std=c++98 -Wall -Wextra, но он совсем не обязательно работает в других компиляторах, по той же причине foo(i).

gcc добавляет следующее к пространству имен std:

template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                                       double>::__type
    sqrt(_Tp __x)
    { return __builtin_sqrt(__x); }

То есть он добавляет inline double sqrt(X) для всех целочисленных типов X.

Я ценю, что g ++ делает все возможное, чтобы выручить меня и все такое, но есть ли (законный) способ заставить его диагностировать ошибку в моем коде?

[Редактировать: я использую gcc 4.3.4, но если другие версии gcc могут диагностировать его, меня тоже интересует этот факт!]

Ответы [ 2 ]

2 голосов
/ 19 мая 2011

Это «полезное» дополнение стандартной библиотеки GCC не соответствует C ++ 03, согласно
[lib.global.functions] / 2 :

Вызов глобальной сигнатуры функции [описанной в определении стандартной библиотеки] ведет себя так же, как если бы реализация не объявляла никаких дополнительных сигнатур глобальной функции.

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

2 голосов
/ 19 мая 2011

Вы хотите цитату из FDIS?

Последний абзац из 26.8:

Кроме того, должны быть дополнительные перегрузки, достаточные для обеспечения:

  1. Если какой-либо аргумент соответствует *Параметр 1010 * имеет тип long double, тогда все аргументы, соответствующие параметрам double, эффективно приводятся к long double.

  2. В противном случае, если какой-либо аргумент, соответствующий параметру double, имеет тип double или целочисленный тип, то все аргументы, соответствующие параметрам double, эффективно приводятся к double,

  3. В противном случае все аргументы, соответствующие параметрам double, фактически приводятся к float.

В этом случае он долженбыть пункт 2, который применяется.

...