2010-09-07 3 views
3

перефразировать ВопросРекурсивный шаблон?

я обнаружил, что мой первоначальный вопрос был недостаточно ясен и repliers поняли мою проблему. Итак, позвольте мне попытаться прояснить:

Скажем, у меня есть два класса:

struct C { void(*m_func)(C*); }; 
struct D { std::function<void(D*)> m_func; }; 

Теперь я хочу, чтобы сделать общий вариант из двух, так что я что-то вроде этого:

template<typename Func> 
struct G 
{ 
Func m_func; 
}; 

Но теперь я не знаю, как экземпляр этого класса:

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; //??? 

Оригинал Quest ион:

Привет,

У меня есть класс шаблона, который может принимать указатель на функцию или станд :: объект функции в качестве параметра. Все хорошо, пока эта функция не использует указатель класса шаблона в подписи:

#include <functional> 

template<typename Func> 
class C 
{ 
public: 
    C() {} 
    Func m_func; 
}; 

void foo() 
{ 
    C<void(*)(C*)> c; 
    C<std::function<int(C*)>> d; 
} 

Соответствующие ошибки компилятора:

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 

Как это решить эту проблему?

ответ

2

Вы не можете назвать рекурсивный шаблон вне себя, но вы можете назвать его внутри, так как список параметров не является обязательным в самоссылки.

Проблема заключается в том, чтобы рассказать шаблону, как передать себя «чему-то».

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; 
+0

Спасибо. Я попробую это. :) – user418680

2

C - шаблон класса, а не класс. У вас не может быть объекта типа C или указатель на C; у вас могут быть только объекты экземпляров C, например C<int> или C<float>.

2

В этой строке:

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

жирным шрифтом C (курсив) не определяет параметры шаблона. Вы должны указать, какой тип C* этот указатель функции принимает, указав тип в < > скобки.

+0

спасибо. Я понимаю, почему компилятор жалуется. Но я не знаю, как это решить. C *)> *)> очевидно, не работает.:( – user418680

+0

Что они говорят шаблон <имяТип Func> класса C { общественность: C() {} Func m_func; }; недействительного Foo() { C <недействительного (*) (C *)> c; C *) >> d; } int main() { } – Chubsdad

+0

Да, я понимаю. Но я хочу, чтобы C * был указателем своего типа. то есть. если все это не шаблон, оно будет выглядеть так: class C {void (* m_func) (C *); }; – user418680

1

Помогает ли это?

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

У вас не может быть рекурсивного шаблона.

+0

Есть ли какая-либо рекурсия, которую не поддерживают шаблоны? – Potatoswatter

Смежные вопросы