я заметил странное поведение в отношении функции поиска, когда полагаться на функцию, которая будет определена позднее:Имя поиска для перегруженных функций, определенных позже
#include <iostream>
template <typename T>
void foo(const T&)
{
std::cout << "Basic" << std::endl;
}
template <typename T>
void bar()
{
T x;
foo(x);
}
void foo(const int& x)
{
std::cout << "int:" << x << std::endl;
}
int main()
{
bar<int>();
}
Выход:
Basic
По какой-то причине, я ожидал используйте foo
внутри bar
, чтобы найти перегрузку под ней. Перемещение перегрузки foo
выше bar
делает вывод желаемого int:0
(или просто написание декларации).
Такое же поведение не появляется, чтобы применить к перегрузке бинарного оператора:
#include <iostream>
struct Foo {} foo;
template <typename T>
void operator<<(const Foo&, const T&)
{
std::cout << "Basic" << std::endl;
}
template <typename T>
void bar()
{
T x;
foo << x;
}
void operator<<(const Foo&, const int& x)
{
std::cout << "int:" << x << std::endl;
}
int main()
{
bar<int>();
}
Выход:
int:0
У меня есть два вопроса, первый: почему это поведение, как это и почему он отличается от перегрузки оператора? Второе: если у меня есть именованная функция (например, мое использование foo
), есть ли способ написать функцию bar
таким образом, чтобы обнаружить перегруженный foo
s, объявленный позже в блоке перевода?
Я считаю, что второе определение должно быть * не * найдено в любом случае. Определения функций, не видимые из объявления шаблона, рассматриваются только в случае ADL, который здесь не встречается. –
Во втором случае 'operator <<' вводится через ADL, потому что 'Foo' вводит пространство имен' :: '. –