#c #templates #function #stl
#c #шаблоны #функция #stl
Вопрос:
Перефразированный вопрос
Я обнаружил, что мой первоначальный вопрос был недостаточно ясен, и ответчики неправильно поняли мою проблему. Итак, позвольте мне попытаться прояснить:
Допустим, у меня есть два класса:
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 в качестве своего параметра. Все в порядке, пока эта функция не использует указатель на класс template в своей подписи:
#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
Как это решает эту проблему?
Ответ №1:
Вы не можете назвать рекурсивный шаблон вне самого себя, но вы можете назвать его внутри, поскольку список параметров необязателен при самостоятельной ссылке.
Тогда проблема заключается в том, чтобы указать шаблону, как передать себя «чему-то».
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:
C
это шаблон класса, а не класс. У вас не может быть объекта типа C
или указателя на C
; у вас могут быть только объекты экземпляров C
, такие как C<int>
или C<float>
.
Ответ №3:
В этой строке:
C<void(*)(C *)> c;
Выделенный жирным шрифтом C (выделено мной) не определяет параметры шаблона. Вы должны указать, какой тип C*
принимает указатель на эту функцию, указав тип в <> скобках.
Комментарии:
1. Спасибо. Я понимаю, почему компилятор жалуется. Но я не знаю, как это решить. C<void( * )( C<void( * )(C<???>*)>* )> очевидно, что это не работает. 🙁
2. Они говорят, что шаблон<функция имени типа> класса C { public: C() {} Функция m_func; }; void foo() { C<void( )(C<int> )> c; C<std::function<int(C<int>*)>> d; } int main(){ }
3. Да, я понимаю. Но я хочу, чтобы C * был указателем своего собственного типа. т. е. если все это не является шаблоном, это выглядело бы так: class C { void( * m_func)(C * ); };
4. Или это: class C { std::function<int(C*)> m_func; };
Ответ №4:
Помогает ли это?
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);
}
Ответ №5:
У вас не может быть рекурсивного шаблона.
Комментарии:
1. Существует ли какой-либо вид рекурсии, который шаблоны не поддерживают?