Код шаблона в основном состоит из двух проходов. Первый проход просто смотрит на код и проверяет, что он синтаксически корректен и что любой независимый код корректен. Под независимым кодом я подразумеваю код, который не зависит от параметров шаблона.
После этого происходит второй проход после фактического создания шаблона. На этом этапе больше нет зависимого кода, так как все параметры шаблона известны, и компилятор может проверить код, как это было бы для любого не шаблонного кода.
In
void heapify_down(std::vector<T> &vec)
{
nonexisting_func(vec);
}
вызов nonexisting_func
зависит от vec
из-за ADL , а vec
зависит от T
, поэтому его компиляция отложена. Это синтаксически правильно, поэтому дальнейшая проверка не будет выполнена, пока он не будет создан. Если вы изменили main на
int main( )
{
std::vector<int> foo;
heap<int> my_heap;
my_heap.heapify_down(foo);
return 0;
}
, так что экземпляр heapify_down
фактически будет создан, вы получите ошибку компилятора, такую как
main.cpp:22:7: error: use of undeclared identifier 'nonexisting_func'
nonexisting_func(vec);
^
main.cpp:30:12: note: in instantiation of member function 'heap<int>::heapify_down' requested here
my_heap.heapify_down(foo);
^
1 error generated.
Вы также получите ошибку, используя
void heapify_down(std::vector<T> &vec)
{
::nonexisting_func(vec);
}
Потому что теперь у нас больше нет неквалифицированного имени, поэтому ADL игнорируется, означая, что ::nonexisting_func
больше не является зависимым именем.
С
void heapify_down(std::vector<T> &vec)
{
a;
nonexisting_func(vec);
}
a
hasn не зависит от T
, поэтому компилятор пытается его найти. Он не может найти его, поэтому вы получаете ошибку. Если вместо этого вы сделали
void heapify_down(std::vector<T> &vec)
{
this->a;
nonexisting_func(vec);
}
, то снова вы не получите ошибку, пока не создадите экземпляр функции, поскольку a
теперь зависит от this
, а this
зависит от T
.