tuple of void member functions - c++

I'm attempting to create a tuple which contains a pointer to a void member function, but I'm having trouble making it work.
here's my code:
class A
{
void dostuff(){ cout<<" doing stuff "}
};
class B
{
A* aobj;
typedef vector<vector<tuple<int,int,void(A::*)()>>> sequence;
sequence Sequence;
void getinfo(int n1, int n2, void(A::*func)())
{
Sequence.resize(1);
Sequence[0].push_back(make_tuple(n1,n2,(aobj->*func)()))//<--ERROR HERE
};
};
it's giving me the error "invalid use of void expression."
I also tried to simplify the function to :
void getinfo(void(A::*func)())
{
make_tuple((aobj->*func)());
}
and it still gives me the same error.

As Igor Tandetnik pointed out, (aobj->*func)() was calling the method and returning void to the make_tuple() function. To pass a member pointer, it should instead be make_tuple(n1,n2,func).

Related

Trying to push_back into a vector pointing to an abstract class

Compiling my code that contains this class:
class Dessin
{
private:
vector<Figures*>T;
public:
void ajouteFigure(const Figures& f) const
{
for(auto element: T)
{
T.push_back(f);
}
}
};
yields an error:
[Error] no matching function for call to
'std::vector::push_back(const Figures&) const'
This is what I'm supposed to do in the main()
Dessin s;
s.ajouteFigure(Cercle(1.1));
Why wouldn't this work?
Assuming Cercle is a class name, you're trying to push a value where a pointer is expected.
To "fix" the error you should change your ajouteFigure prototype to accept Figures pointers and non-const this:
void ajouteFigure(Figures* f)
Then you should call it passing a pointer to a Figures object, i.e. created with a new expression:
s.ajouteFigure(new Cercle(1.1));
That being said, this code seems pointless. You're adding the pointer as many times as you have elements in the vector (which is always 0 in the example you provided).
Using raw pointers is also unadvised, you should use smart pointers like std::unique_ptr, although that would break the current code.
Consider this, less improper, example:
class Dessin
{
private:
vector<unique_ptr<Figures>> T;
public:
void ajouteFigure(unique_ptr<Figures> f)
{
T.push_back(move(f)); // just once
}
};
and at the call site:
Dessin s;
s.ajouteFigure(make_unique<Cercle>(1.1)); // C++≥14
or, if you can't use C++14:
Dessin s;
s.ajouteFigure(unique_ptr<Figures>(new Cercle{1.1}));
Just to add to this, I think you would be better to make it a template function and create the right object inside the function with arguments to the constructor passed as function parameters.
This way you don't have to create a std::unique_ptr or use new every time you call the function.
Here's a basic implementation:
class Dessin{
public:
template<typename T, typename ... Args>
void ajouteFigure(Args &&... args){
figures.emplace_back(new T(std::forward<Args>(args)...));
}
private:
std::vector<std::unique_ptr<Figures>> figures;
};
Then using the class is less error-prone:
int main(){
Dessin d;
d.ajouteFigure<Cercle>(1.1);
}

Passing default parameter to function C++

I want to call function either with default arguments or given by me, but default arguments are specified class private variables, simplified sample here:
Class::Something
{
public:
void setI(int i);
private:
void func(int i = this->i_default, j=this, k=this->k_default, l=this->l_default);
int i_default; // May be different for different instances.
int k_default; // May be different for different instances.
int l_default; // May be different for different instances.
}
So when i call func() it takes default i_variable or when i call func(4) it takes 4 argument without changing i_default value.
I know im doing something wrong couse i get error:
Error 1 error C2355: 'this' : can only be referenced inside non-static member functions or non-static data member initializer
is there some kind of way to achive such behaviour?
is there some kind of way to achive such behaviour?
Use function overload (Thanks #PiotrSkotnicki):
void func(int i);
void func() { func(i_default); }
You can declare i_default as const static (Thanks to #TartanLama).
const static int i_default=1;
Here is the working program.
You can also use function overloading. But this uses less code than function overloading!
The standard is quite clear about this. You explicitely cannot use this in the default parameter. You seem to be bound to use overloading for achieving this result:
void func(int i);
void func() { func(i_default); }
If you want to keep down the functions you could use a sentry that would allow func decide if it's to use the default. In the simpliest form:
void func(int* pi = NULL) {
int i = pi ? *pi : i_default;
// rest of the function
}
This method could be extended to use a helper class:
#include <cstdio>
template <typename C, typename T>
class Defaltable {
T val;
T C::* ptr;
public:
Defaltable(int C::* p) {
ptr = p;
val = 0;
}
Defaltable(T x) {
val = x;
ptr = NULL;
}
T fetch(C* p) {
return ptr ? p->*ptr : val;
}
};
class Foo {
int i_default;
public:
Foo(int dflt) {
i_default = dflt;
}
int func(Defaltable<Foo, int> x = &Foo::i_default) {
return x.fetch(this);
}
};
int main()
{
Foo c(42);
printf("%d\n", c.func(1));
printf("%d\n", c.func());
}

C++ // Invalid use of nonstatic data member

Code::blocks says "Invalid use of nonstatic data member" . Why this error ?
class counter {
public:
counter()=default; //default contructor
friend void upg(){++val;} //function that increases "val" by 1
private:
int val=0;
};
upg() is not a member function. Therefore it cannot access val without an instance of counter. This would compile, although it probably doesn't make much sense:
friend void upg() { counter c; c.val++; }
A better solution might be to make upg() a member,
class counter
{
public:
counter()=default; // some pointless code "documentation"
void upg(){ ++val; } //function that increases "val" by 1
private:
int val=0;
};
or, if you really need a non-member, give it a counter parameter:
friend void upg(counter& c) { c.val++; }
I think you don't understand what a friend function is.
Let's create an object with a friend function, a regular function, and a method:
#include <set>
#include <utility>
class counter {
public:
void method_inc();
friend void friend_inc(counter & c);
private:
int val = 0;
};
void counter::method_inc() {
this->val++;
void friend_inc(counter & c) {
c.val++;
}
void nonfriend_inc(counter & c) {
c.val++; // Error: val is private.
}
int main() {
counter c;
c.method_inc();
friend_inc(c);
nonfriend_inc(c);
}
Let's talk about our functions:
The method has an implicit this that allows it to access the object it was called with. In this case, that would be the c in c.member_inc().
The function nonfriend_inc() has to have an argument of the object that it is using. But it will also fail to build because counter::val is private and it's not a friend function.
The function friend_inc() also doesn't have an implicit this. But because it is a friend function to class counter, it can access the private members of that object.

How can I pass a member function pointer into a function that takes a regular function pointer?

I have a player class which looks like this (stripped down to what is needed for this problem):
class Player
{
public:
Player();
~Player();
void kill();
void death();
void reset();
};
The kill(), death(), and reset() functions look like this:
void Player::kill()
{
void (*dPtr)() = &death;
Game::idle(dPtr, 48);
}
void Player::death()
{
reset();
}
void Player::reset()
{
//resets
}
The idle function is a static memeber function of Game, which takes a function pointer and an integer n, and calls the function after n tick. Here is the function, the implementation shouldn't matter:
class Game {
static void idle(void (*)(), int);
};
This code gives me the error:
ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&Player::death' [-fpermissive]
So I change the line from
void (*dPtr)() = &death;
to
void (Player::*dPtr)() = &Player::death;
to solve that issue. But then my call to the idle function is incorrect, as it takes a regular function pointer, and I am passing in a member function pointer, and thus gives me the error:
no matching function for call to 'Game::idle(void (Player::*&)(), int)'
So my question is:
How can I pass the member function pointer Player::*dPtr into the idle function, which takes a void (*)() as an argument?
Or is there another way I can solve my previous error which forbids me from taking the address of an unqualified member function to form a pointer to a member function?
Another answer mentions that you need two pointers. However C++ already comes with containers for doing just this, so it would make your code a lot simpler to use those. (In C++03, some of the std:: items below were std::tr1::).
Sample code:
#include <iostream>
#include <functional>
struct Game
{
static void idle( std::function<void()> func, int x )
{ std::cout << "x = " << x << "\n"; func(); }
};
struct Player
{
void death() { std::cout << "player.death\n"; }
void kill() { Game::idle( std::bind(&Player::death, this), 48 ); }
};
int main()
{
Player p;
p.kill();
}
Lifetime note: std::bind binds by value. Using *this means a copy of the Player is made and stored in the std::function object, copied around with it as necessary.
Using this means the function object stores a pointer, so if you actually store the function object in Game::idle you must take care that this Player is not destroyed before removing this function object from Game::idle's list.
To call a member function through a pointer, you need two pointers: the pointer to the function itself, and a pointer to an object to be this. Your Game::idle API does not support this usage. You need to change it so that it passes at least one argument (conventionally of type void *) to the callback. Then you can use the following pattern:
struct Player
{
// ...
void kill();
// ...
static void call_kill(void *self);
};
void Player::call_kill(void *self)
{
static_cast<Player *>(self)->kill();
}
struct Game
{
static void idle(void (*)(void *), void *, int);
};
void Game::idle(void (*callback)(void *), void *arg, int ticks)
{
// ...
callback(arg);
// ...
}
void kill_player_delayed(Player *p, int ticks)
{
Game::idle(Player::call_kill, static_cast<void *>(p), ticks);
}
You have to write a static call_X method for every instance method X you want to call.
An alternative approach, which is arguably more C++-idiomatic and flexible, and involves less explicitly written-out code, but has higher runtime costs (three indirect function calls and a heap allocate-free cycle per invocation, instead of a single indirect function call), is to have Game::idle take an object of a particular class, with a virtual callback method. That class is then given a template subclass that can call anything that implements operator(), such as the result of std::bind.
struct Runnable { virtual ~Runnable(); virtual void invoke() = 0; };
template <typename T> struct TRunnable : Runnable {
TRunnable(T target) : target(target) {}
void invoke() { target(); }
private:
T target;
};
template <typename T> TRunnable<T>* make_Runnable(T obj)
{ return new TRunnable<T>(obj); }
struct Game
{
static void idle(Runnable *, int);
};
void Game::idle(Runnable *r, int ticks)
{
// ...
r->invoke();
delete r;
// ...
}
struct Player
{
// ...
void kill();
// ...
};
void kill_player_delayed(Player *p, int ticks)
{
Game::idle(make_Runnable(std::bind(&Player::kill, p)), ticks);
}
You cannot make Game::idle take the result of std::bind directly because that object's type is unspecified (and varies depending on how you call std::bind), so it can only be used as an argument to a template function call. A virtual method call to an adapter class is the only way to keep Game::idle compiled out-of-line and still let it use bound-call objects.
In either approach, beware object lifetime issues. In particular, if Game::idle does not call its callback before returning, you need to
make sure that both the original object, and (in the second approach)
the object returned by make_Runnable survive until the callback fires. This is why make_Runnable uses new.
Because I really don't like the answer that casts void*'s to other objects (almost never necessary in C++!) and nobody has posted an answer using the suggestions in the comments I'm going to suggest this.
Use a templated type for your callback!
Like this:
class Game{
template<typename Func>
static void idle(Func &&func, int i){
// game stuff
func();
// other game stuff
}
};
Then you don't lose all of your type safety (casting void*) and it should be the fastest solution.
Also, where you are assigning a function pointer, you can change the code to be far more readable in this case:
void Player::kill(){
Game::idle([this](){this->death();}, 48);
}
Which is far nicer than having to write the correct function pointer type.
You cannot do that simply because pointer to [static] function is a single pointer sizeof void*. In contrary member function need more information, e.g. two pointers: one for this and another one for the function itself so member function pointer has sizeof > sizeof(void*).
Therefore you have two options:
to change signature of your idle() to this void idle(void (*)(), void*, int); so you will be able to pass this somehow.
Or make static variable that will hold this pointer. But that assumes that only one death() can be at idle queue at any given moment of time.
1) is what people do usually in such cases.

How to call pointer member function inside a class definition?

How do I call a pointer member function within a class definition?
My code:
//Myclass.h
struct Booking{
int src;
int dest;
int pos;
};
class MyClass{
public:
void ExecutePlan();
private:
struct FlightPlan{
string name;
vector<Booking> bookings
};
typedef FlightPlan FP;
FP firstplan;
FP secondplan;
void FirstPlan(Booking& book);
void SecondPlan(Booking& book);
void Execute(FP& fplan, void (MyClass::*mptr)(Booking& book));
};
// Myclass.cpp
void MyClass::FirstPlan(Booking& book){
// do something with booking
}
void MyClass::SecondPlan(Booking& book){
// do something with booking
}
void MyClass::Execute(FP& fplan, void(MyClass::*mptr)(const FlightPlan& fp)){
for (int i=0; i<.fplan.bookings.size(); i++){
cout << "Executing Plan: "<< fplan.name << endl;
// Problematic line ...
mptr(bookings[i]); // <----- can't compile with this
}
}
void MyClass::Execute(){
// is this the correct design to call this member functions ???
Execute(firstplan, &MyClass::FirstPlan)
Execute(secondplan, &MyClass::SecondPlan)
}
How can i structure the Execute Function to receive a member function as a pointer?
Pls: Am a newbie in C++, maybe the design is weird!!
Paul
How to call pointer member function inside a class definition?
Unlike member names, member pointers aren't implicitly applied to this. You have to be explicit:
(this->*mptr)(fplan.bookings[i]);
is this the correct design to call this member functions ???
Apart from a few obvious errors (such as missing ; here and there, saying const FlightPlan& where you mean Booking& in the definition of Execute), the rest of the code looks fine. Specifically
Execute(firstplan, &MyClass::FirstPlan)
Execute(secondplan, &MyClass::SecondPlan)
is the correct syntax for obtaining the member-function pointers.
The operator to call a member function pointer is ->*. Since you want to call it on this object, you need to use
(this->*mptr)(bookings[i]);