Reputation: 195
I know we can do the following,
template <class CONTAINER>
void f(CONTAINER *c){}
int main(){
std::vector<int> v;
f(&v);
std::set<int> s;
f(&s);
}
Then, I want an alternative (convenient for my project), like the following,
template <class CONTAINER>
void f(CONTAINER<int> *c){} // the CONTAINER is the name of a template class
But, the compiler outputs
error: ‘CONTAINER’ is not a template
Is this possible?
Upvotes: 4
Views: 891
Reputation: 16448
You are looking for a template template parameter:
#include <set>
#include <vector>
template<template<typename> typename CONTAINER>
void f(CONTAINER<int> *){}
int main(){
std::vector<int> v;
f(&v);
std::set<int> s;
f(&s);
}
"Matching template template parameters to compatible arguments" is a C++17 feature. This won't work with C++14 because std::vector
has more than one template parameter.
You need -frelaxed-template-template-args
to compile this code with Clang, see: Template template parameter in function templates and How is P0522R0 breaking code?
An alternative way is to use template template parameters with variadic templates to avoid "Matching template template parameters to compatible arguments":
#include <set>
#include <vector>
template<class T, template<class, class...> class CONTAINER, class... Args>
void f(CONTAINER<T, Args...> *){}
int main(){
std::vector<int> v;
f(&v);
std::set<int> s;
f(&s);
}
or
#include <set>
#include <vector>
template<template<class, class...> class CONTAINER, class... Args>
void f(CONTAINER<int, Args...> *){}
int main(){
std::vector<int> v;
f(&v);
std::set<int> s;
f(&s);
}
This works with C++11.
Upvotes: 5