Abs и использование пространства имен std

Скажем, я использую using namespace std (бесспорно плохая практика) и что Я использую функцию abs в своем коде (чтобы получить перегруженная абсолютная функция). Чтобы быть конкретным, мой MWE:

#include <cmath>
#include <iostream>
#include <stdlib.h>

using namespace std; 

int main(int argc, char* argv[]) {

 double f(-0.4);
 std::cout<<"abs(f) = "<<abs(f)<<std::endl;

}

Если я закомментирую строку using namespace std;, то вывод будет

abs(f) = 0

иначе вывод

abs(f) = 0.4

Чего я не понимаю, так это того, как в последнем случае вызывается «правильная» функция abs, учитывая, что даже в stdlib.h есть функция abs, которая возвращает только int.

На самом деле второй ответ на этот вопрос говорит о том, что использования using namespace std; может быть недостаточно. Это правда? Мой MWE, кажется, противоречит этому.

Я работаю в Linux и использую gcc-4.8, что, возможно, является наиболее проблематичной комбинацией для разрешения зависимостей.


person MaviPranav    schedule 27.12.2016    source источник
comment
Не могу воспроизвести. У меня работает с gcc 6.2.1   -  person Sam Varshavchik    schedule 27.12.2016
comment
Ваша программа у меня тоже работает. Это должно быть проблемой компилятора.   -  person Yousaf    schedule 27.12.2016
comment
Обновлен для включения версии компилятора gcc-4.8.   -  person MaviPranav    schedule 27.12.2016


Ответы (1)


Когда вы используете

using namespace std;

вы вводите в область видимости следующие перегрузки abs:

std::abs(int)
std::abs(float)
std::abs(std::complex)

Вызов abs(f) разрешается в std::abs(float).

Если вы не используете

using namespace std;

есть только одна функция abs, которую вы можете использовать.

abs(int)

Следовательно, вызов abs(f) разрешается в abs(int).

Вы по-прежнему можете удалить строку using namespace std; и использовать std::abs(f) вместо abs(f).

person R Sahu    schedule 27.12.2016
comment
Имеет смысл, мне в основном было интересно, был ли какой-либо сценарий, в котором, несмотря на наличие using namespace std; в файле, вызывался вызов abs(int) при простом указании abs. - person MaviPranav; 27.12.2016
comment
@MaviPranav, поскольку вы приняли ответ, я предполагаю, что вы получили ответы, которые вам нужны. Если нет, дайте мне знать. - person R Sahu; 28.12.2016
comment
Ответ правильный, но для меня все еще не определено, может ли существовать контрпримерная ситуация, то есть abs(int) вызывается из вызова abs, несмотря на то, что using namespace std; используется. - person MaviPranav; 28.12.2016
comment
Безусловно, abs(int) можно было бы вызвать, если бы #include ‹cmath› был удален (даже с использованием пространства имен std). Этот тип молчаливого изменения при удалении заголовка смертельно опасен для больших приложений. К счастью, практически все компиляторы выдают предупреждение об усечении значения типа double до целого числа. Еще одна причина обратить внимание на предупреждения компилятора. - person Rob L; 15.07.2017