Разрешение перегрузки, порядок определенных функций и шаблонов - PullRequest
5 голосов
/ 12 марта 2019

Рассмотрим следующий фрагмент кода:

template<class T>
std::enable_if_t<std::is_integral<T>::value, bool> func(T value) {
    std::cout << "T\n";
    return func(static_cast<int64_t>(value));
}

bool func(int64_t value) {
    std::cout << "int64_t\n";
    return true;
}

int main() {
    func(1);
}

Это вызывает бесконечную рекурсию.Однако замена порядка определения этих двух функций (если bool func(int64_t value) определено до шаблона 1) помогает избежать этой проблемы.

Почему это так?Имеет ли значение перегрузка порядка функций?

Ответы [ 3 ]

4 голосов
/ 12 марта 2019

Имеет ли значение перегрузка функций?

Это не меняет результат разрешения перегрузки, но результат name lookup ; что происходит до разрешения перегрузки.

(акцент мой)

Для имени, используемого в глобальной области (пространство имен верхнего уровня), вне какой-либо функции, класса или пространства имен, объявленного пользователем, глобальная область до использования имени :

Это означает, что для вызова func внутри шаблонного func может быть найден только сам (и добавлен в набор перегрузки), версия без шаблона не будет рассматриваться вообще.

Как вы уже видели, если вы измените их порядок объявления, оба значения func будут найдены и учтены при следующем разрешении перегрузки, и будет выбран не шаблон func (как и ожидалось).

2 голосов
/ 12 марта 2019

Когда компилятор анализирует первую функцию (шаблон), он ничего не знает о второй перегрузке func. Синтаксический анализ выполняется сверху вниз по исходному файлу.

По этой причине вам необходимо иметь объявления символов, прежде чем использовать их. Это также означает, что наличие объявления из bool func(int64_t); вверху решит вашу проблему.

1 голос
/ 12 марта 2019

Имеет ли значение порядок перегрузок функций?

Порядок перегрузок имеет значение в том смысле, что если набор перегрузок вызывается до объявления потенциальной перегрузки, это еще не объявленофункция не участвует в разрешении перегрузки.

Порядок перегрузок, объявленных до вызова функции, не имеет значения.

...