Проблемы с преобразованием класса шаблона - невозможно вывести вызываемую функцию - PullRequest
0 голосов
/ 14 февраля 2020

Как мне заставить следующий код работать должным образом?

Версия без шаблона компилируется отлично, но версия шаблона с треском проваливается. Почему версия шаблона не может определить, какую версию функции вызывать и как это исправить? Я думал о добавлении в шаблон AT оператора класса, который неявно преобразуется в BT, но он тоже не работает.

class A {};

class B
{
    public: 
    B(A){};
};

void func(B){};

template<typename T>
class AT {};

template<typename T>
class BT
{
    public: 
    BT(AT<T>){};
};

template<typename T>
void funcT(BT<T>){};

int main()
{
    func(A{});
    funcT(AT<int>{}); // unable to deduce the funcT template argument
    funcT<int>(AT<int>{}); // compiles but I don't want to write that

    return 0;
}

Есть немые исправления, такие как написание версии функции, которая принимает AT<T> и приводит к * 1007. *. Но я не хочу писать кучу функций, когда все должно работать как есть. Я мог бы понять это, если бы это был неоднозначный вызов ...

Ответы [ 2 ]

2 голосов
/ 14 февраля 2020

Неявное преобразование не будет учитываться при выводе аргумента шаблона :

Вывод типа не учитывает неявные преобразования (кроме корректировок типа, перечисленных выше): это работа для разрешение перегрузки , что происходит позже.

Это означает, что для funcT, который ожидает BT<T>, но передал AT<int>, T не может быть выведен и не вызывается.

Обходной путь, как вы показали, заключается в явном указании аргумента шаблона, чтобы обойти вывод аргумента шаблона.

Не шаблонные функции не имеют такой проблемы; они не требуют вывода аргументов шаблона.

0 голосов
/ 14 февраля 2020

Другой ответ объяснил, что происходило, но есть способ обойти это

template<class T, template<class>class Temp, typename std::enable_if<std::is_convertible< Temp<T>, BT<T>>::value, bool>::type = true>
void funcT(Temp<T> t) { 
    auto bt = static_cast<BT<T>>(t);
}

Это может быть вызвано fooT(A<int>{});, а также fooT(B<int>{});, имеющим такое же поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...