Почему можно использовать std :: max и std :: min, даже если я не #include & lt; алгоритма & gt ;?

#include <iostream>

int main()
{
int value1 = 1, value2 = 10;
std::cout << "Min = " << std::min(value1,value2) <<std::endl;
std::cout << "Max = " << std::max(value1,value2)<< std::endl;
}

Насколько я знаю, min а также max функции определены в <algorithm>,

Если бы я не сказал препроцессору включить <algorithm> почему код все еще работает?

15

Решение

Скорее всего, что-то внутри iostream прямо или косвенно включил какой-то другой заголовок, который определяет std::min а также std::max, (Может быть, algorithm Сам был включен. Возможно, какой-то внутренний заголовок, который используется для реализации вашей стандартной библиотеки C ++.)

Вы не должны полагаться на это поведение. Включают algorithm если вы хотите std :: min и std :: max.

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

Напомним, однако, что #include выполняет текстовую подстановку. Когда строка #include обрабатывается, она удаляется из файла .cpp и заменяется содержимым файла, на который она указывала.

У большинства компиляторов есть возможность вывести результаты работы препроцессора, чтобы вы могли отследить, что в том числе и что. В своем комментарии к ответу kmort вы сказали, что используете Visual Studio Express. Командная строка для предварительно обработать файл в файл с помощью компилятора Visual C ++ cl /P foo.cpp, Используя этот вывод, мы можем найти, что определение std::max исходит из конкретного заголовка реализации xutility, (Поместить курсор внутри текста «std: max» и нажать клавишу F12 в Visual Studio еще быстрее.: -])

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

Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\iostream
Note: including file:  C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\istream
Note: including file:   C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\ostream
Note: including file:    C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\ios
Note: including file:     C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xlocnum
Note: including file:      C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\streambuf
Note: including file:       C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xiosbase
Note: including file:        C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xlocale
Note: including file:         C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\stdexcept
Note: including file:          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xstring
Note: including file:           C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0
Note: including file:            C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xutility
20

Другие решения

Какой компилятор вы используете?

До этого я видел компиляторы, которые несколько «прощают» общие элементы, определенные в libc или libstdc ++. Он будет тянуть за ссылками для вас. Другими словами, вам не нужно указывать ссылку на нее или включать заголовок. Это просто работает. Хотя я бы не ожидал такого min() а также max()Это не слишком удивительно.

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

2

По вопросам рекламы [email protected]