У меня есть следующий сценарий:C++ шаблон вычет не может вывести аргумент шаблона
struct AP;
struct B
{
B() : m(2) {}
int m;
};
struct A : private B
{
A() : B(), n(1) {}
private:
int n;
friend AP;
};
struct AP
{
AP(A& a) : a_(a) {}
template<typename T>
struct A_B {
using type = typename std::enable_if< std::is_base_of< typename std::remove_reference<T>::type,
A >::value,
T >::type;
};
template<typename T>
operator typename A_B<T>::type()
{
return static_cast<T>(a_);
}
template<typename T>
typename A_B<T>::type get()
{
return static_cast<T>(a_);
}
int& n() { return a_.n; }
private:
A& a_;
};
int main()
{
A a;
AP ap(a);
ap.n() = 7;
const B& b = ap.get<const B&>();
//const B& b = ap; candidate template ignored: couldn't infer template argument 'T'
//auto b = static_cast<const B&>(ap); candidate template ignored: couldn't infer template argument 'T'
std::cout<<b.m;
}
комментируемого линии не будет компилировать. Clang ++ отмечает, что «шаблон-кандидат игнорируется: не удалось вывести шаблонный аргумент« T »«
Почему я не могу получить ссылку на базу А с оператором литья? Я думаю, что код будет выглядеть намного приятнее.
Вашей комментировали линию попытаться преобразовать 'ap' в ссылку типа' b' а ' ap 'имеет тип' AP', который не имеет отношения к 'B' или' A'. Как вы ожидаете, что это сработает? – wasthishelpful
@wasthishelpful: Я думаю, что OP пытается сделать, это преобразовать элемент 'a_' экземпляра' AP' в 'B', который должен быть действительным, потому что' A' происходит от 'B'. – AndyG