Member function template using boost::function - c++

The following TestClass works:
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
void ext_fun(const float f, int i)
{
std::cout << f << '\t' << i << std::endl;
}
template <typename T>
class TestClass
{
public:
boost::function <void (const T)> test_fun;
};
int main()
{
TestClass<float> tt;
tt.test_fun = std::bind(ext_fun, std::placeholders::_1, 10);
tt.test_fun(2.1);
return(0);
}
However, I would prefer to define test_fun as a member function template, i.e., something like
class TestClass
{
public:
template <typename T> boost::function <void (const T)> test_fun;
};
But if I do it, I get this compiler error: "error: data member ‘test_fun’ cannot be a member template"
Is it possible to define a member function template using a boost::function? If yes, how?
Thank you
--Matteo

Is it possible to define a member function template using a boost::function? If yes, how?
I think you have a little bit of confusion going on here. A function template is, first of all, a function. Your test_fun is not a function, it's a member object of the class TestClass. Member objects can't be templatized in C++.

Related

Pass template function to std::bind?

I want to use std::bind with template function. Is it somehow possible?
P.S. It is IMPORTANT to use std::bind, because I know at least one solution through lambdas and want to find out if there is std::bind solution.
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
struct foo : std::enable_shared_from_this<foo>
{
void f()
{
// doesn't compile, error : no matching function for call to 'bind'
auto cb = std::bind(&foo::handle, shared_from_this(), placeholders::_1, placeholders::_2);
}
template <typename T, typename U>
void handle(T, U)
{
}
};
int main()
{
return 0;
}
handle is not a template function. There are no "template functions". handle is a function template, ie it is a template, it is not a function. You cannot std::bind to a template. You can only std::bind to a callable.
The trick is to defer instantiation of the template and deduction of the template parameters to when the function is actually called:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
struct foo {
struct handle_caller {
template <typename T,typename U>
void operator()(foo* f, T t,U u){
f->handle(t,u);
}
};
void f()
{
auto cb = std::bind(handle_caller{},this, placeholders::_1, placeholders::_2);
}
template <typename T, typename U>
void handle(T, U)
{
}
};
int main()
{
return 0;
}
The callable passed to bind is an object of a concrete type handle_caller. It is not a template. Only when cb is called the parameters are forwarded to handle_caller::operator() where the template arguments can be deduced.
Lambdas can do this out-of-the box, because a lambda with auto arguments is of a concrete type and only its operator() is a template:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
struct foo {
void f()
{
auto cb = std::bind([](auto f,auto t,auto u){ f->handle(t,u);},this, placeholders::_1, placeholders::_2);
}
template <typename T, typename U>
void handle(T, U)
{
}
};
int main()
{
return 0;
}
However, once you use the lambda there is no need for std::bind anymore, because you can bind the parameters via a lambda capture. std::bind is the ancient way to bind parameters, it is convoluted and has clunky syntax. I have read of cases that can be done with std::bind but not with a lambda, but I have never encountered one.
PS: Note that I removed the shared_from_this stuff from your code, because I know it can be used wrong easily, but I am not sure how to use it correctly. As cb is only local to foo::f there is no need to worry about the lifetime of this in the example code.
&foo::handle is not valid C++, because foo::handle is not a function. foo::handle<int, int> is a function, and foo::handle<double, std::string> is a different function.
You will have to wrap it in something, so you may as well use a lambda.

Why these C++ cases instantiate different templates

I am trying to write some functionality where I need to save different functions and later extract their arguments' types. So I'm using the function signature as template parameter. But I get somewhat unexpected results.
Here's the code:
#include <functional>
#include <iostream>
template <class T>
struct foo
{
foo()
{
std::cout << "class T" << std::endl;
}
};
template <class Ret, class Arg>
struct foo<Ret(Arg)>
{
foo()
{
std::cout << "Ret(Arg)" << std::endl;
}
};
template <class T>
void save(std::function<T>)
{
new foo<T>();
}
int main(int argc, char* argv[])
{
std::function<void(void)> someFoo;
save(someFoo);
return 0;
}
So if the variable someFoo is a function with type void(void), it instantiates the first template, foo<T>. But if I change it to void(int), than I get the desired specialized template instantiated. Why is that?
In C++, having a void argument is actually the same as having no argument at all (unlike in C, by the way). So it would match a specialization for Ret(), but it can't match a specialization for Ret(Arg).
void(void) is the exact same as void() - the second void is optional and makes no difference.
That's why the first template with no parameters is used.

C++ pass function to call by template type by parameter

I have a class A that is a wrapper around a container of template objects of type T. T is expected to be a class in this use case. A has no reference whatsoever on the provided T type.
Is there a way to implement a function in A to call a function of T passed by parameters? Pseudocode:
template <class T>
void A:callFunction(functionToCall, functionParams, ...) {
objectT->functionToCall(functionParams, ...);
}
objectT is of type T, functionToCall is void
I have not been able to find if it's really impossible to do in C++98 and why. Any possible workaround would help too.
It is possible, for example:
#include <iostream>
using namespace std;
struct bar
{
void say(int a, int b)
{ cout << a << ' ' << b << endl; }
};
template <typename T>
struct foo
{
template <typename fptr>
void say(fptr f, int a, int b)
{
(i.*f)(a, b);
}
T i;
};
int main() {
foo<bar> f;
f.say(&bar::say, 10, 100);
}
(this will compile with -std=c++98 for example on gcc)
If you don't want to use a template parameter for the member function, something like;
void say(void (T::*f)(int, int), int a, int b)
{
(i.*f)(a, b);
}
Ought to work too..
As #Nim said, it's possible, as long as you know at least the number of arguments to be forwarded (types can be "templated") and define a function only for that number of arguments (or multiple functions using overloading). There's no possibility to create a function forwarder for any number of arguments.
This is only possible in C++11 using the "variadic template" feature:
template <class T, class Function, class... Args>
void A::callFunction(Function functionToCall, Args... functionParams) {
bind(objectT, functionToCall, functionParams...);
}
Note that this:
objectT->functionToCall(functionParams, ...);
is not possible at all because you cannot specify a symbol defined inside a class as a "free symbol". However you can try to exploit the "pointer to member" feature and do this:
(objectT->*functionToCall)(functionParams, ...);
as long as this "functionToCall" is a pointer to member function of the class to which's object objectT points. For example:
x->callFunction(&T::something, a, b);

why is it necessary to include template parameter before every function even if we are not using diduced type in the function?

Why are we suppose to use template parameters at front of every function even if we are not using deduced template parameters in the function. As we can see that i am not using template parameter _T in printP() function (around 30) then why it is required to include template syntax at front of this function.
NOTE: This is very simplified version of my big class, and it might look silly because it is very small but, consider a situation where you are using template for only few [2-3] function of your class but you are bound to type (even copy past) this lengthy template syntax at front of every function but i am asking why??.
Is there any way to get of this
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
template<typename _T>
class Thing{
int _p;
_T _k;
public:
Thing(int p, _T k):_p(p),_k(k){}
void printK();
void printP();
};
template<typename _T>
void Thing<_T>::printK(){
cout << _k << endl;
}
template<typename _T>
void Thing<_T>::printP(){
cout << _p << endl; // as we can see that i am not using template paramerter "_T"
} // here in this function then why it is required to include template syntax
int main()
{
Thing<int> a(1,2);
a.printK();
a.printP();
}
Because the function PrintK is member of template class Thing<_T>. For a member function definition outside the class, the function name also includes class name(to which it belongs, here it belongs to Thing), since Thing is template, so function name requires you to provide template parameter (T here).
e.g.
Function definition outside class requires the following syntax
**
return type class name:: function name (argument list)
*
Here class (Thing) is template class, so its name will also require type (like Thing<_T>).
I hope you got my point.
Its usually a good idea to restrict the members and functions of a template class to those that are dependent on the template parameters. Non-dependent members and functions can be put in a separate non=template class (is there a better name?). For example:
#include <iostream>
using namespace std;
class ThingBase
{
public:
ThingBase(int p)
: _p(p)
{
}
void printP();
protected:
int _p;
};
void ThingBase::printP(){
cout << _p << endl;
}
template<typename _T>
class Thing : public ThingBase {
_T _k;
public:
Thing(int p, _T k)
: ThingBase(p),
_k(k){}
void printK();
};
template<typename _T>
void Thing<_T>::printK(){
cout << _k << endl;
}
int main()
{
Thing<int> a(1,2);
a.printK();
a.printP();
}

Is defining function pointer as a new type with a template type as an argument not possible in C++?

In C, I can do this.
typdef void(TRAVERSAL_CALLBACK*)(int a);
That would then allow me to pass function pointers to other functions as arguments, with that function having 1 argument of type int.
I've been working with templates, and currently, passing the function pointer to the method works like this:
void my_function(void(TRAVERSAL_CALLBACK*)(T &data));
Now, is it possible if I define a new type with argument of type T. I have tried but it has failed to compile.
typedef void(TRAVERSAL_CALLBACK*)(T &data);
I'm using C++11. Is this something that I have to accept as not possible, or is there an idomatic way to do this in C++11 that I am not aware of?
Yes, in C++11 it's possible, thanks to the "new" using:
template<typename T>
using TRAVERSAL_CALLBACK = void(*)(T &data);
Notice however that in C++ you'd probably just make the whole type of the callback a template, to allow the usage of other types of callable objects (functors, lambdas, ...).
In C++11, there is template type aliasing using the using statement, example shown below:
#include <iostream>
using namespace std;
template <typename T>
T foo() {return 10;}
template <typename T>
using fptr = T (foo*)(void);
int main()
{
fptr<int> x1 = foo<int>;
fptr<double> x2 = foo<double>;
cout << "Hello World" << endl;
return 0;
}
However, in your case you most likely don't need to go that far. If you define the type within the scope of the template, it should work fine:
template <typename T>
struct bar
{
typedef T (*qiz)(void);
void baz(qiz q)
{
std::cout << q << std::endl;
}
};