The OP has been answered but I want to chime in because the immediate cause of the problem is not recursion, as others claim. The simplest reason this wouldn't work is that class templates are not types. They are templates. Similarly, function templates are not functions either. So all of this is nonsensical:
template<typename T> int function_template(int);
typedef int function_type(int);
void eats_a_function(function_type&); // needs a reference to function
std::vector< std::vector > vec0; // std::vector is not a type
std::vector< std::list > vec1; // std::list is not a type
eats_a_function(function_template); // function_template is not a function
Notice that in the vec1
case, std::list
is not related to std::vector
. The template is fully defined (assuming header inclusion) at the point of instantiation. It still won't work.
Instead, the following works:
std::vector< std::vector<int> > vec2; // std::vector<int> is a type
std::vector< std::list<double> > vec3; // std::list<double> is a type
eats_a_function(function_template<long>); // function_template<long> is a function
Notice that in the vec2 case, it's fine to pass an instantiation of the template itself.
For the record, a toy solution to the toy problem on writing a template that refers to itself, using the proverbial layer of indirection:
// expects a template that expects a type
template<template<class> class T> struct indirection {};
// forward decl. for defaulting the parameter
template<typename T> struct recursive;
// template that expects a type
template<typename T = indirection<recursive> > struct recursive {};
Not terribly powerful given the few things that are possible with a template (the T
parameter inside indirection
). It's of course possible to write a rebind
-style metafunction that returns an instantiation of T
.