Rephrased Question
I found that my original question wasn't clear enough and the repliers misunderstood my problem. So let me try to clarify:
Let's say I have two classes:
struct C { void(*m_func)(C*); };
struct D { std::function<void(D*)> m_func; };
Now I want to make a generic version of the two, so I do something like this:
template<typename Func>
struct G
{
Func m_func;
};
But now I don't know 开发者_开发技巧how to instantiate this class:
G<void(*)(G*)> c; //error
G<std::function<void(G*)>> d; //error
G<void(*)( G<void(*)(G<???>*)> *)> c; //???
G<std::function<void( G<std::function<void(G<???>*)>> *)>> d; //???
Original Question:
Hi,
I have a template class that can take a function pointer or a std::function object as its parameter. All is fine until that function uses a pointer of the template class in its signature:
#include <functional>
template<typename Func>
class C
{
public:
C() {}
Func m_func;
};
void foo()
{
C<void(*)(C*)> c;
C<std::function<int(C*)>> d;
}
Relevant compiler errors:
error C2955: 'C' : use of class template requires template argument list
error C3203: 'function' : unspecialized class template can't be used as a template argument for template parameter 'Func', expected a real type
error C2955: 'std::tr1::function' : use of class template requires template argument list
How do it solve this problem?
You can't name the recursive template outside itself, but you can name it inside, as the parameter list is optional in a self-reference.
The problem then becomes one of telling the template how to pass itself to "something."
template< typename T >
struct fptr_taking_type { // this template is essentially a function
typedef void (*type)( T ); // from types to types, the result being
}; // the typedef
template< typename T >
struct stdfn_taking_type {
typedef function< void (*)( T ) > type;
};
template< template< typename > class F >
struct G {
typename F< G * >::type m_func; // this declares the member variable
};
...
G< fptr_taking_type > q;
C
is a class template, not a class. You can't have an object of type C
or a pointer to a C
; you can only have objects of instantiations of C
, like C<int>
or C<float>
.
In this line:
C<void(*)(C *)> c;
The bolded C (emphasis added) does not specify template parameters. You should specify what type of C*
this function pointer takes, by specifying a type in <> brackets.
Does this help?
void foo1(){}
template<typename Func>
class C
{
public:
C(Func f) : m_func(f) {}
Func m_func;
C<Func> *mp; // it is a pointer,
};
void foo()
{
C<void (*)(void)> c (foo);
}
int main(){
C<void (*)(void)> c(foo);
}
You cannot have a recursive template.
精彩评论