You can provide a wrapper that accepts template template parameter (read below):
template <template <typename> class TT,
typename T = int>
using my_vector = std::vector<TT<T>>;
my_vector<integer> vec{}; // works
my_vector<integer, long> vecLong{}; // using non-default type
Templates have different types of template parameters:
Each parameter in a parameter-list may be:
a non-type template parameter;
a type template parameter;
a template template parameter.
template <typename>
struct with_type_parameter{};
template <template <typename> class>
struct with_template_template_parameter{};
So, there is an explicit difference for compiler between your integer<> and integer.
- The first one is a type explicitly instantiated from a template parameter.
- The second one is a template template.
So, when you instantiate a class template std::vector with a template template integer instead of a type integer<> for an argument, you get the error you have. Because these two things are different for class templates.
However, there is a different behavior fo function templates, since they are allowed for overloading.
Here is an example for you: https://godbolt.org/z/cbnss17aj
template <typename>
struct with_typename{};
// can't have that. class template can only be specialized when declared
// template <template <typename> class>
// struct with_typename{};
#include <iostream>
template <typename>
void with_typename_fn()
{
std::cout << "type" << std::endl;
}
// perfectly fine, since function template overloading is allowed in C++
template <template <typename> class>
void with_typename_fn()
{
std::cout << "template template" << std::endl;
}
template <typename>
struct non_defaulted{};
template <typename = int>
struct defaulted{};
int main()
{
with_typename_fn<int>(); // ok
with_typename_fn<non_defaulted>(); // also ok
with_typename_fn<defaulted>(); // also ok, but will resolve to template template specialization!
}
Output:
type
template template
template template