简体   繁体   English

递归模板?

[英]Recursive template?

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. 我有一个模板类,可以将函数指针或std :: function对象作为其参数。 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? 它是如何解决这个问题的?

C is a class template, not a class. C是类模板,而不是类。 You can't have an object of type C or a pointer to a C ; 你不能有类型的对象C或一个指向C ; you can only have objects of instantiations of C , like C<int> or C<float> . 你只能拥有C实例化的对象,比如C<int>C<float>

In this line: 在这一行:

C<void(*)(C *)> c;

The bolded C (emphasis added) does not specify template parameters. 粗体C (强调添加)不指定模板参数。 You should specify what type of C* this function pointer takes, by specifying a type in <> brackets. 您应该通过在<>括号中指定类型来指定此函数指针所用的C*类型。

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;

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);
}

你不能有一个递归模板。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM