Звонки, как:
arity_t idx = distance(labels.begin(), found_it) + 1;
Это означает, что distance
найдено через ADL и, следовательно, рассматриваются все связанные пространства имен. Это может оказаться проблематичным, если, например, есть два пространства имен, обеспечивающие одинаково применимую перегрузку для distance
:
Live On Coliru
#include <iterator>
#include <vector>
namespace OyVeh {
struct X { };
template <typename It>
size_t distance(It, It) { return 42; } // just to throw in a wrench
}
int main() {
std::vector<OyVeh::X> v{3};
auto f = v.begin();
auto l = v.end();
// now f and l have both `::std` and `::OyVeh` as associated namespaces. The following is ambiguous:
return distance(f, l);
}
Существует примерно 2 способа исправить это:
- удалить неоднозначное объявление
distance
из связанного пространства имен (это может быть невозможно, если, например, конкурируют std::distance
и boost::distance
)
- отредактируйте вызовы, чтобы исключить зависимость от ADL (например, укажите их как
std::distance(...)
или заключите в скобки (distance)(...)
)
Отображение обходных путей:
Live On Coliru
{
using OyVeh::distance;
return (distance)(f, l); // parentheses suppress ADL
}
return std::distance(f, l); // also works, obviously
return OyVeh::distance(f, l); // but beware the meaning might change