Reputation: 451
I'm using a template library in which class B is a templated class parametrized by class A. I have a declaration
template <class A, template <class A> class B>
void foo(){
B<A> x;
}
later on I want to invoke this as
foo<A, B>();
where X is a concrete class in the library and Y is a particular templated concrete class in the library. However, I get the titled error abour template argument deduction/substitution failed. If I change the declaration of foo to remove the templates and subsitute in X and Y, then it all works ok. I also tried
foo<X, Y<X> >();
which failed with the same message. Can someone explain why this is happening?
I'm using gcc 5.3.0
Here's a complete example which gives the indicated behavior
#include <vector>
template <class A, template <class A> class B>
void foo() {
B<A> x;
}
void bar() {
foo<int, std::vector>();
}
Upvotes: 0
Views: 170
Reputation: 2313
You have two issues that I can see.
First is that std::vector
takes more than one template argument so the template template parameter template<class A> class B
will never match std::vector
.
Second and slightly less of an issue is that the class A
here template<class A> class B
shadows the previous class A
here template <class A/*here*/, template <class A> class B>
To fix both of these issues you can declare the second template argument as an nameless variadic template like so: template <class...> class B
.
Combining everything you get:
#include <vector>
template <class A, template <class...> class B>
void foo() {
B<A> x;
}
void bar() {
foo<int, std::vector>();
}
Edit:
If you would like to only use B in the form of B<A>
you could do one of a few things:
template <class A, template <class...> class B>
void foo() {
using C = B<A>;
C x;
}
OR:
template <class A, template <class...> class B, class C = B<A>>
void foo() {
C x;
}
OR (depending on the larger point of your code) you could just accept the whole thing as one template parameter:
template <class A>
void foo() {
A x;
}
void bar() {
foo<std::vector<int>>();
}
Upvotes: 3
Reputation: 7302
std::vector
is not templated on one class, so it does not match your type. You can coerce it to match by
template <class X> using MyVector = std::vector<X>;
and that will work. C++17 will just plain fix this to work as you expected it to.
Upvotes: 1