Рекурсивный шаблон? - PullRequest
       15

Рекурсивный шаблон?

3 голосов
/ 07 сентября 2010

Перефразированный вопрос

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

Допустим, у меня есть два класса:

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

Оригинальный вопрос:

Привет,

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

#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

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

Ответы [ 5 ]

2 голосов
/ 07 сентября 2010

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

Тогда возникает проблема объяснения шаблону, как передать себя «чему-то».

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;
2 голосов
/ 07 сентября 2010

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

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

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

2 голосов
/ 07 сентября 2010

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

1 голос
/ 07 сентября 2010

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

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 голосов
/ 07 сентября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...