function template as template parameter

consider the following program: template <typename T> void function_template(T value) { std::cout << __PRETTY_FUNCTION__ << std::endl; } struct function_template_wrapper { template <typename T> static void call(T value) { function_template<T>(value); } }; int main(int argc, char* argv[]) { int i; function_template_wrapper::call<int>(i); } Is it possible to somehow parameterize the struct function_template_wrapper such that I can pass function_template as a parameter? E.g. function_template_wrapper<function_template>::call<int>(i); would call function_template<int>(i), and function_template_wrapper<other_function_template>::call<int>(i); would call other_function_template<int>(i) Underlying problem: I want to somehow pass a name of a function template to a class, that will instantiate the function template for a number of types (known at compile time), and store these instantiations in function objects, for later use. Best regards, -- Ares Lagae Computer Graphics Research Group, Katholieke Universiteit Leuven http://www.cs.kuleuven.be/~ares/

Hi! do you mean this? #include <iostream> template<class T> void function_template(T value) { std::cout << value << std::endl; } struct function_template_wrapper { template<class T, void(*Fct)(T)> static inline void call(T value) { Fct(value); } }; int main(int argc, char* argv[]) { function_template_wrapper::call<int, function_template<int> >(10); return 0; } May be you will take a look at boost::function library. Best Regards, Ovanes On Tue, May 29, 2007 17:57, Ares Lagae wrote:
consider the following program:
template <typename T> void function_template(T value) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
struct function_template_wrapper { template <typename T> static void call(T value) { function_template<T>(value); } };
int main(int argc, char* argv[]) { int i; function_template_wrapper::call<int>(i); }
Is it possible to somehow parameterize the struct function_template_wrapper such that I can pass function_template as a parameter?
E.g. function_template_wrapper<function_template>::call<int>(i); would call function_template<int>(i), and function_template_wrapper<other_function_template>::call<int>(i); would call other_function_template<int>(i)
Underlying problem: I want to somehow pass a name of a function template to a class, that will instantiate the function template for a number of types (known at compile time), and store these instantiations in function objects, for later use.
Best regards,
-- Ares Lagae Computer Graphics Research Group, Katholieke Universiteit Leuven http://www.cs.kuleuven.be/~ares/
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Just a small addition to my example: I was unsure if compiler will deduce the type of the function param without explicit template specialization. At least MSVC 8 did it. Hope this is so by C++ standard. Here is the example: include <iostream> template<class T> void function_template(T value) { std::cout << value << std::endl; } template<class T> void other_function_template(T value) { std::cout << value*value << std::endl; } struct function_template_wrapper { template<class T, void(*Fct)(T)> static inline void call(T value) { Fct(value); } }; int main(int argc, char* argv[]) { function_template_wrapper::call<int, function_template>(10); function_template_wrapper::call<int, other_function_template>(10); return 0; } With Kind Regards, Ovanes

Ovanes Markarian wrote:
Hi!
do you mean this?
function_template_wrapper::call<int, function_template<int> >(10);
Thanks for the reply, but it's not really what I want. I need some mechanism to pass a function template, not an instantiation of a function template. For example: template <typename T> void callback() {} class { // invalid syntax //a kind template template parameter of template function type template <template <typename T> void (*function_pointer) (T)> void set_callback() { std::tr1::function<void (T1)> f_t1 = &function_pointer<T1>; std::tr1::function<void (T2)> f_t2 = &function_pointer<T2>; ... std::tr1::function<void (Tn)> f_tn = &function_pointer<Tn>; } } -- Ares Lagae Computer Graphics Research Group, Katholieke Universiteit Leuven http://www.cs.kuleuven.be/~ares/

my closest attempt is this: #include <iostream> #include <tr1/functional> template <typename T> void callback_1(T value) { std::cout << __PRETTY_FUNCTION__ << std::endl; } template <typename T> void callback_2(T value) { std::cout << __PRETTY_FUNCTION__ << std::endl; } template <typename T, void (*FunctionPointer) (T)> struct function_template_wrapper { typedef void (*FunctionPointerType) (T); static FunctionPointerType function_pointer; static std::tr1::function<void (T)> function() { return std::tr1::function<void (T)>(FunctionPointer); } }; template <typename T, void (*FunctionPointer) (T)> typename function_template_wrapper<T, FunctionPointer>::FunctionPointerType function_template_wrapper<T, FunctionPointer>::function_pointer = FunctionPointer; template <typename T> struct callback_1_wrapper : public function_template_wrapper<T, callback_1<T> > {}; template <typename T> struct callback_2_wrapper : public function_template_wrapper<T, callback_2<T> > {}; template <template <typename> class function_template_wrapper> void set_callback() { function_template_wrapper<int>::function()(int()); function_template_wrapper<double>::function()(int()); function_template_wrapper<float>::function()(int()); } int main(int argc, char* argv[]) { set_callback<callback_1_wrapper>(); set_callback<callback_2_wrapper>(); } -- Ares Lagae Computer Graphics Research Group, Katholieke Universiteit Leuven http://www.cs.kuleuven.be/~ares/

Well, if you switch to functors, instead of functions I can offer you the following example ;) But I am unsure if it really suits your needs. #include <iostream> template<class T> struct function_template { void operator()(T value)const { std::cout << value << std::endl; } }; template<class T> struct other_function_template { void operator()(T value)const { std::cout << value*value << std::endl; } }; struct function_template_wrapper { template<class T, template<class> class Function> static inline void call(T value, Function<T> f = Function<T>()) { f(value); } }; int main(int argc, char* argv[]) { function_template_wrapper::call<int, function_template>(10); other_function_template<int> of; function_template_wrapper::call(10, of); } On Wed, May 30, 2007 08:54, Ares Lagae wrote:
my closest attempt is this:
[...]
-- Ares Lagae Computer Graphics Research Group, Katholieke Universiteit Leuven http://www.cs.kuleuven.be/~ares/
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
With Kind Regards, Ovanes Markarian

Ares Lagae wrote:
Ovanes Markarian wrote:
Hi!
do you mean this?
function_template_wrapper::call<int, function_template<int> >(10);
Thanks for the reply, but it's not really what I want.
So you're looking for something like template template parameters for function templates? As you probably know, there is no such language feature. However, it's common practice to use function objects for the use case you describe: // A Function Object struct my_func { template<typename T> void operator()(T const &) const { // [...] } typedef void result_type; // It's also possible to use a result type that // depends on T. Further reading: // http://www.boost.org/libs/utility/utility.htm#result_of }; Now you can pass objects of that type to another function template, or just pass the type 'my_func' to a class template as template argument (for generic components it's usually a good idea to provide a way to initialize the object - maybe a default argument in the ctor, otherwise valid types are restricted to be DefaultConstructible and users can't set an initial state). You can also stuff such an object into a Boost.Function, hard-wiring it towards a certain signature in order to call it from anywhere (such as another translation unit where the type of the function object is unknown). Regards, Tobias
participants (3)
-
Ares Lagae
-
Ovanes Markarian
-
Tobias Schwinger