Calling a member function with member data by using for_each - c++

Dear all, I would like to call a member function (that expects a reference) for each object of (let's say) a vector that is a member of the same class, as the following code shows:
#include <functional>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
struct Stuff {
double x;
};
class Test {
public:
void f1(Stuff & thing);
void f2(void);
vector<Stuff> things;
};
void Test::f1(Stuff & thing) {
; // do nothing
}
void Test::f2(void) {
for_each(things.begin(), things.end(), f1);
}
int main(void)
{
return 0;
}
This codes gives me a compiler error related to unresolved overloaded function type . I have tried also with bind, but it seems that the references requisite in f1 is one problem. I know I am missing something important here, so I take this opportunity to solve my problem and to learn. At the moment, I can't install boost, but I would like to know also if boost is useful to solve this problem. Thanks in advance.

The function you want to call cannot be simply identified by f1 but should be referred to as &Test::f1 (as in : member function f1 of class Test)
Function f1 does not take a single argument : as any non-static member function it has an implicit this parameter of type Test * const
Finally, a standard bind won't be able to do the trick because it doesn't handle parameters passed by reference.
Boost.Bind would indeed be a great option :
std::for_each(things.begin(), things.end(), boost::bind(&Test::f1, this, _1));

Related

Pointer to member type incompatible with object type → What is the cause?

Recently I ran into a compiler (GNU g++ 4.9.2) error like this:
ProceduralTimerTaskAdapter.cpp:25:13: error: pointer to member type ‘void (Poco::Util::Timer::)(Poco::Util::TimerTask&)’ incompatible with object type ‘Poco::Util::ProceduralTimerTaskAdapter’
Here is the relevant code (which is almost self-contained, save for the necessary Poco libs):
ProceduralTimerTaskAdapter.h:
#include <Poco/Util/Timer.h>
#include <Poco/Util/TimerTask.h>
#include <Poco/Util/TimerTaskAdapter.h>
#ifndef PROCEDURALTIMERTASKADAPTER_H
#define PROCEDURALTIMERTASKADAPTER_H
using namespace std;
using namespace Poco::Util;
typedef void (*Callback) (TimerTask&);
namespace Poco {
namespace Util {
class ProceduralTimerTaskAdapter : public TimerTaskAdapter <Timer> {
public:
ProceduralTimerTaskAdapter (Callback procedure); // Constructor
void run (); // Method defining the main thread
protected:
~ProceduralTimerTaskAdapter (); // Destructor (not for general use)
private:
ProceduralTimerTaskAdapter (); // Default constructor (not for general use)
Callback procedure; // The callback procedure called by the timer.
};
}
}
#endif
ProceduralTimerTaskAdapter.cpp:
// This is the implementation of the ProceduralTimerTaskAdapter class.
#include <iostream>
#include <Poco/Util/Timer.h>
#include <Poco/Util/TimerTask.h>
#include <Poco/Util/TimerTaskAdapter.h>
#include "ProceduralTimerTaskAdapter.h"
using namespace std;
using namespace Poco::Util;
ProceduralTimerTaskAdapter::ProceduralTimerTaskAdapter (Callback procedure) : TimerTaskAdapter<Timer>::TimerTaskAdapter (*(new Timer ()), procedure)
{
this -> procedure = procedure;
}
ProceduralTimerTaskAdapter::~ProceduralTimerTaskAdapter ()
{
}
void ProceduralTimerTaskAdapter::run ()
{
TimerTask &task = *this;
(this ->* procedure) (task);
}
What I wanna do is, in fact, build an extension of the well-known TimerTaskAdapter to handle callback functions, which are not tied to a specific class (because they are situated in main.cpp, for instance). I override the virtual method run () with a very simple self-made one, which calls the callback. After having handled several different errors, I ended up with this apparent class mismatch I can't solve myself. I even don't understand why the compiler states a class name, whose name is Poco::Util::Timer:: (Why does it end with ::?). As ProceduralTimerTaskAdapter defines a member named procedure, why does the compiler expect another class?
Thank you.
Derive from Poco::Util::TimerTask (like in Poco::Util::TimerTaskAdapter class) and override run method in which you will call procedures.
class ProcedureAdapter : public Poco::Util::TimerTask {
public:
typedef void (*Callback)(TimerTask&);
ProcedureAdapter (Callback c) : callback(c) {;}
void run () {
callback(*this); // call some procedure which takes TimerTask
}
Callback callback;
};
void fun (Poco::Util::TimerTask&) {
cout << "fun was invoked" << endl;
}
void fun2 (Poco::Util::TimerTask&) {
cout << "fun2 was invoked" << endl;
}
int main()
{
Poco::Util::Timer t;
t.schedule (new ProcedureAdapter{&fun},1,1);
t.schedule (new ProcedureAdapter{&fun2},1,1);
The syntax ->* expects a left-hand operator of type pointer to class object (such as this) and a right-hand operator of type pointer to member function of that class. But in
TimerTask &task = *this; // line 24
(this ->* procedure) (task); // line 25
procedure is not a pointer to a member function of ProceduralTimerTaskAdapter. So your code is ill-formed. procedure is simply a pointer to a free (non-member) function taking a TimerTask& and returning void. If ProceduralTimerTaskAdapter is derived from
TimerTask then the following code should compile
TimerTask &task = *this;
(this -> procedure) (task);
or shorter
procedure(*this);
using the fact that pointers to functions can syntactically be used like the function.
Edit. It appears (from your comments to another answer) that your code was ill-formed in yet another way, namely that ProceduralTimerTaskAdapter was not derived from TimerTask. Then, of course already line 24 (not just 25) should produce an error. It seems, therefore, that you didn't show us the precise same code as the one that created the error message, or not all the errors it causes.

Invoking a member method pointer from another method

In class Foo I have two methods, assign_handler() and call_handler().
The actual handler code is in the main.cpp which is do_this(). do_this() uses the some global variables in main.cpp,
I think Foo has to have a function pointer as member which will be assigned in assign_handler() which is what I did. However I'm having trouble invoking assign_handler() i.e. calling do_this(), from call_handler().
Note: call_handler() itself is call by a sigaction in Foo.
EDIT: I tried producing a MCVE as suggested in the comments. I've used gedit to create the files and compile it using g++ in command line. The code works. However in my Eclipse project I get the errors shown in inline comments of the code.
MCVE:
//Foo.h
class Foo{
public:
void (*funptr)(void);
void call_handler();
void assign_handler (void(*func1)(void));
Foo(){};
};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
funptr = func1;
}
void Foo::call_handler(){
funptr();//error: invalid use of member Foo::funptr in static member function; from this location
//or
//this->funptr();//error: 'this' is unavailable for static member functions
}
//main.cpp
#include <iostream>
#include "Foo.h"
using namespace std;
void do_this(void);
int main(void){
Foo foo;
foo.assign_handler(do_this);
foo.call_handler(); //this won't be called explicitly, it is assigned as a handler for a sigaction
int x;
cin>>x;
}
void do_this(void){
cout<<"done"<<endl;
}
I'll divide my answer in two parts. First I'll attempt to answer your question, then I'll attempt to tell you what you actually want to do.
Your question is how to assign a function pointer to a member variable and then call it from a static member function. Since the function pointer is a member of the class you will also require a pointer to the class in order to call the function pointer. A way of achieving this is to add a static member to your class that holds a pointer to the (single) instance of your class. Since you indicated that you will be using this as a signal handler, you won't want to use multiple handlers anyway.
So, something like this:
//Foo.h
class Foo{
public:
static void call_handler();
void assign_handler (void(*func1)(void));
Foo() {
ms_instance = this;
};
private:
void (*funptr)(void);
static Foo *ms_instance;
};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
funptr = func1;
}
void Foo::call_handler(){
ms_instance->funptr();
}
A more general way would be to store a function object:
//Foo.h
#include <functional>
#include <utility>
class Foo{
public:
static void call_handler();
template<typename func>
void assign_handler (func&& handler)
{
m_handler = std::forward(handler);
}
Foo() {
ms_instance = this;
};
private:
std::function<void(void)> m_handler;
static Foo *ms_instance;
};
//Foo.cpp
#include "Foo.h"
void Foo::call_handler(){
ms_instance->m_handler();
}
This way you can assign lots of different stuff as the handler:
// Function pointers
foo.assign_handler(do_this);
// Lambdas
foo.assign_handler([]() { /* do something */ });
// Binds - you should probably prefer lambdas...
foo.assign_handler(std::bind(&MyClass::member_func, &myObj));
Now what you actually want to do when you are going to handle a signal is a bit more complicated. Remember that signal handlers can only call certain functions (async-signal-safe functions) - otherwise things may get ugly. Therefore there is a common trick that you should perform called the self pipe trick. Essentially you should have a signal handler that receives the signal, but only calls write on a pipe with the signal number as the data to send. Then you have another place in your code that calls select on the pipe and then read to read the signal number. You then call the appropriate handler function which is then allowed to do whatever you like.
An example of this is here: http://man7.org/tlpi/code/online/book/altio/self_pipe.c.html
Be aware that it can be slightly tricky to get this right in a cross-platform manner, especially if multithreaded.

Functions and function pointers in C++

With reference to the following code
#include <iostream>
using std::cout;
using std::endl;
#include <vector>
using std::vector;
void function() {
cout << "Hello World" << endl;
}
int main() {
vector<void (*) ()> functions;
functions.push_back(function); // (1) no error
functions.push_back(&function); // (2) no error
for (const auto& func : functions) {
func();
}
// vector<decltype(function)> vec; // (3) error
return 0;
}
There seems to be an error when I uncomment (3), I am just trying to understand the reasoning behind this. When I pass in a function as the argument to a templated function does it resolve the type to a function pointer? It would make sense for the compiler to deduce all function types as such to a function pointer but why then does the decltype() not resolve to a function pointer?
decltype(function) is void() - a function.
what you need is the decayed version of a function - void(*)():
std::decay<decltype(function)>::type
std::vector < std::decay<decltype(function)>::type > myPtrFunctionVec;
PS.
if you're working with VC++ (visual stdio) you can easily see the type deduced from decltype by printing typeid(decltype(XXX)).name(). VC++, unlike other compilers, gives the undecorated name of a type. very handy for metaprogramming debugging.
EDIT:
as #Daniel Jour has commented, the solution decltype(&function) workd as well, because the construct &f gives the pointer to f, which is what you need

sort() - No matching function for call to 'swap'

Just spent about an hour trying to figure out why I would get 20 error messages of the type "Semantic issue - no matching function for call to 'swap'" when I try to build the following class (in XCode).
test.h
#include <iostream>
#include <string>
#include <vector>
class Test{
std::vector<std::string> list;
void run() const;
static bool algo(const std::string &str1, const std::string &str2);
};
test.cpp
#include "test.h"
void Test::run() const {
std::sort( list.begin(), list.end(), algo );
}
bool Test::algo(const std::string &str1, const std::string &str2){
// Compare and return bool
}
Most of the people with the same problem seem to have made their algorithm a class member instead of a static member, but that is clearly not the problem here.
It turns out it's a very simple problem, but not very obvious to spot (and the error message doesn't do a very good job in helping out either):
Remove the const declaration on run() - voilá.
The compiler refers to swap because std::sort internally uses function swap. However as member function run is declared as constant function
void run() const;
then the object of the class itself is considered as a constant object and hence data member list also is a constant object
std::vector<std::string> list;
So the compiler tries to call swap with parameters that are constant references or even are not references and can not find such a function.

conversion of boost::shared_ptr in boost::python function call

Consider the following example:
#include "Python.h"
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
class A {};
class B : public A{};
void foo(boost::shared_ptr<A>& aptr) { }
BOOST_PYTHON_MODULE(mypy)
{
using namespace boost::python;
class_<A, boost::shared_ptr<A> >("A", init<>());
class_<B, boost::shared_ptr<B>, bases<A> >("B", init<>());
def("foo", foo);
}
if I call the python code
import mypy
b = mypy.B()
mypy.foo(b)
I get
ArgumentError: Python argument types in
mypy.foo(B)
did not match C++ signature:
foo(boost::shared_ptr<A> {lvalue})
I have googled around quite alot, but I can't find a good explanation / fix / workaround for this. Any help is quite welcome!
The problem is that you're asking for a non-const reference to a shared_ptr<A>, and your b instance in Python simply doesn't contain one; it contains a shared_ptr<B>. While shared_ptr<B> can be implicitly converted to shared_ptr<A>, shared_ptr<B>& cannot be implicitly converted to shared_ptr<A>&.
If you can modify foo to take a shared_ptr<A>, or shared_ptr<A> const &, that will solve your problem.
If not, you'll need to also wrap a version that accepts shared_ptr<B>&.