У меня есть функция, принимающая в качестве аргумента шаблонный класс с несколькими параметрами (см. «Func2» в следующем коде). Мне бы хотелось, чтобы функция могла принимать в качестве аргумента класс, унаследованный от типа agument, и автоматически разрешать типы шаблонов путем апскейтинга. В следующем примере это нормально для функции ‘func1’, но, очевидно, это невозможно сделать, когда аргумент является классом с несколькими шаблонами, как для функции ‘func2’.
Сообщение об ошибке гласит: «Шаблон кандидата игнорируется: ошибка замещения: аргумент шаблона шаблона имеет параметры шаблона, отличные от соответствующего параметра шаблона шаблона». Я понимаю (и отчасти согласен) с сообщением. Но это тот же случай для ‘func1’, и он работает нормально.
Итак, мой вопрос, есть ли способ, которым я могу трактовать переменную ‘d’ как тип ‘C’ путем автоматического обновления при использовании функции? И если да, то как?
Я использую Xcode 5.1.1, clang-503.0.40. и C ++ 11 вариант. Спасибо
template <class T1>
class A {};
class B : public A<int> {};
template <template <class T1> class T, class T1 >
void func1(T<T1> _arg) {}
template <class T1, class T2>
class C {};
template <class T1>
class D : public C<T1,int> {};
template <template <class T1, class T2> class T, class T1, class T2>
void func2(T<T1,T2> _arg) {}int main() {
A<int> a;
B b;
func1(a);//works
func1(b);//works, T1 is resolved
C<float,int> c;
D<float> d;
func2(c);//works
func2(d);//doesn't work,compilation error message: "Candidate template ignored: substitution failure : template template argument has different template parameters than its corresponding template template parameter"
return 0;
}
Нет, нет способа сделать то, что ты пытаешься сделать.
Вы можете использовать псевдоним, хотя, если ваш компилятор поддерживает их:
template < typename T >
using D = C<T,int>;
Я считаю, что это должно соответствовать вашему шаблону функции просто отлично.
Если вы хотите, чтобы D имел другое поведение, вы бы создали частичную специализацию C.
Хорошо, так что лучший вариант, который я нашел, заключается в следующем. Идея состоит в том, чтобы заставить ‘D’ верить, что это класс с несколькими шаблонами, но на самом деле один из параметров шаблона предназначен только для определенного типа (int). Таким образом, «D2» является своего рода как классом с одним шаблоном, так и классом с двумя шаблонами. Есть еще одна частичная специализация при определении шаблона класса D, но на самом деле это только нормальное определение класса D.
template <class T1, class T2>
class C {};
template <class T1, class T2=int>
class D;
template <class T1>
class D<T1,int> : public C<T1,int> {};
template <typename T1>
using D2 = D<T1>;
template <template <class T1, class T2> class T, class T1, class T2>
void func2(T<T1,T2> _arg) {}
int main()
{
C<float,int> c;
D2<float> d;
func2(c);//works
func2(d);//works
//instantiation tests:
D<float> test1;//works -> normal
D<float, int> test2;//works -> not ideal but well ok
D<float, float> test3;//doesn't work -> also normal. States: "Implicit instantiation of undefined template 'D<float, float>' "
return 0;
}