Почему компилятор C ++ выбирает неправильную функцию (шаблоны) - PullRequest
0 голосов
/ 23 февраля 2019

Я провел несколько тестов и столкнулся с этим странным поведением.

struct A{};

struct B : A{};

#include <iostream>

template<class T>
void fn2(T const &){
}

void fn2(A const &){
    std::cout << "Here\n";
}

template<class T>
void fn1(){
    T a;

    fn2(a);
}

int main(){
    fn1<B>();
}

Я очистил код.При запуске, я ожидаю, что он печатает «здесь».Однако это называется шаблонной версией fn2().

Я тоже тестировал в Godbolt.Там я переписал функции fn1() и fn2(), поэтому они возвращают int.В этот момент компилятор поступил правильно.

Вот как я компилирую:

$ gcc -Wall -Wextra -Wpedantic bug.cc  -lstdc++
$ ./a.out 
$ clang -Wall -Wextra -Wpedantic bug.cc  -lstdc++
$ ./a.out 
$ 

1 Ответ

0 голосов
/ 23 февраля 2019

Версия шаблона выбрана потому, что она точно соответствует (T выводится как B).Для вызова не шаблонной версии требуется неявная версия от B до A;тогда версия шаблона побеждает в разрешении перегрузки.

Вы можете применить SFINAE с std::enable_if и std::is_base_of, чтобы исключить версию шаблона из набора перегрузки, когда T выводится как A или его производные классы.

template<class T>
std::enable_if_t<!std::is_base_of_v<A, T>> fn2(T const &){
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...