i keep getting non-standard syntax; use '&' to create a pointer to member
i dont know why its not working.
it works if Resize function is global
minimal example:
#include <GLFW/glfw3.h>
class test {
public:
test(){}
~test(){}
void resize(GLFWwindow* window, int new_width, int new_height) {}
}resizer;
int main(){
auto newwindow = glfwCreateWindow(1, 1, "test", NULL, NULL);
glfwSetWindowSizeCallback(newwindow, resizer.resize);
return 0;
}
the initial problem got kinda solved using static as the function but this created diferent errors in what i want to do here is the simplified problem the problem:
//rough replication of lib functions cannot change these
typedef void(* windowsizefun)(int,int);
void setWindowSizeCallback(windowsizefun fun){}
//the problem
class windowhandler{
private:
int width, height;
static void resize(int new_width, int new_height) {
width =new_width; height =new_height; //error
}
public:
test(){
width =100; height =100;
setWindowSizeCallback(windowhandler::resize);
}
}
int main(){
windowhandler newWindow();
return 0;
}
Your function pointer doesn't match the declaration that's needed to pass into glfwSetWindowSizeCallback().
It must be a static function, and the scope operator :: needs to be applied correctly:
#include <GLFW/glfw3.h>
class test {
public:
test(){}
~test(){}
static void resize(GLFWwindow* window, int new_width, int new_height) {}
// ^^^^^^
} /*resizer*/;
// ^^^^^^^^^^^ No need for this.
int main(){
auto newwindow = glfwCreateWindow(1, 1, "test", NULL, NULL);
glfwSetWindowSizeCallback(newwindow, test::resize);
return 0;
}
Related
I have two classes in my project:
Style
Line
In which, Line is the child of Style, so Line inherits from Style.
I need that when I call a method of the class Style (the parent) from Line (the child), the method of Style calls a method of the child, for your better understanding here is the code:
Line calls the Style function --> Style calls the Line function
Style.h:
#pragma once
class Style
{
public:
void set_size(int width, int height);
protected:
int width, height;
};
Style.cpp:
#include "Style.h"
void Style::set_size(int width, int height)
{
Style::width = width;
Style::height = height;
}
Line.h:
#pragma once
#include "Style.h"
#include <vector>
using namespace std;
class Line : public Style
{
public:
void draw();
vector <vector<char>> matrix;
};
Line.cpp:
#include "Line.h"
void Line::draw()
{
vector <char> row;
int i, j;
for (i = 0; i < Line::height; i++)
{
row.clear();
for (j = 0; j < Line::height; i++)
{
row.push_back('-');
}
Line::matrix.push_back(row);
}
}
Main.cpp:
#include <iostream>
#include "Line.h"
using namespace std;
int main()
{
Line line;
line.set_size(10, 10);
}
Obviously, this code for now does nothing much, it only modifies Style variables.
What I expect is that when I call set_size(), in addition to changing the value of the variables width and height, it will also change the size of the matrix
I don't know how to do what I said before.
I don't even know if it is a good method that Line is a child of Style, in any case other solutions that do not include inheritance are welcome.
Thanks in advance.
You need virtual functions, it would seem that set_size is the one that should be virtual, but this is not the only way to do it.
class Style
{
public:
virtual void set_size(int width, int height);
virtual ~Style() {}
protected:
int width, height;
};
class Line : public Style
{
public:
void draw();
virtual void set_size(int width, int height)
{
Style::set_size(width, height);
... // some code to resize matrix
}
vector <vector<char>> matrix;
};
But I question if this is good design, Style should be an attribute of Line (i.e. a member variable). Inheritance doesn't seem appropriate here, which is why you are struggling to write the code.
I tried to have implementation and declaration in the same file. but you can structure it as you may feel good for your project.
#include <iostream>
#include <vector>
using namespace std;
class Line;
class Style
{
public:
void set_size(int width, int height){
w = width;
h = height;
}
void print(){
cout << w << ", " << h << endl;
}
friend class Line;
protected:
int w, h;
};
class Line : public Style
{
public:
void draw(){
vector <char> row;
int i, j;
for (i = 0; i < w; i++)
{
row.clear();
for (j = 0; j < h; i++)
{
row.push_back('-');
}
matrix.push_back(row);
}
}
vector<vector<char>> matrix;
};
int main()
{
Line line;
line.set_size(10, 10);
line.print();
line.set_size(20, 20);
line.print();
}
We can just overload set_size within Line and call the other set_size from there and also the draw function to recreate the matrix.
This solution provides simple static polymorphism, that means a Line cannot be assigned to a Style - you probably do not need this? So the compiler always statically at compile-time knows, which class an object really is and can call the correct member function. No virtual member functions are needed.
There also were bugs in the draw function, which I corrected below.
The changes to your code are marked with a comment in the following.
// Line.h
#pragma once
#include "Style.h"
#include <vector>
using namespace std;
class Line : private Style // use private inheritance for static polymorphism
{
public:
void draw();
void set_size(int width, int height); // overload set_size (override only for virtual functions)
vector <vector<char>> matrix;
};
// Line.cpp
#include "Line.h"
void Line::set_size(int width, int height)
{
Style::set_size(width, height); // call set_size() function of style
draw(); // draw() to set matrix to new size
}
void Line::draw()
{
Line::matrix.clear(); // clear matrix, if draw() is called more than once
vector <char> row;
int i, j;
for (i = 0; i < Line::height; i++)
{
row.clear();
for (j = 0; j < Line::width; j++) // use Line::width and j++ (there were bugs)
{
row.push_back('-');
}
Line::matrix.push_back(row);
}
}
// Main.cpp
#include <iostream>
#include "Line.h"
using namespace std;
int main()
{
Line line;
line.set_size(10, 10); // calls the enhanced Line::set_size
// The following compilation errors (when the comments are removed) are good, as they prevent wrong usage of the current class definitions
// Style style = line; // would give error, as we have private inheritance and want to prevent 'slicing' and the calling of the wrong member functions; if a Line should be able to be assigned to a Style, you need public dynamic inheritance and virtual functions, as provided in other answers. If you do not need to assign a Line to a Style, use the simpler implementation from this answer.
// Style* stylepointer = &line; // also would give an error
}
Optionally draw() and matrix can be made private in Line.
If you need to call functions (other than set_size) of Style directly, you can use public inheritance, but make all constructors (including default/copy/move) of Style protected, so that only children like Line can call them. This would also prevent assignments of Line to Style.
EDIT: I'm completely changing the original answer since the question was modified too. If I get it right, you would like line.set_size(...) to call first the parent method and then to update the matrix. You cannot do that, because only one method will be called, and not both of them what you could do is add a set_size method for Line that calls Style's one.
line.h should be changed like this:
class Line : public Style
{
public:
void draw();
void set_size(int width, int height);
vector<vector<char>> matrix;
};
and you should append this to line.cpp:
void Line::set_size(int width, int height)
{
// call parent method
Style::set_size(width, height);
// now update matrix
int i, j;
matrix.resize(height);
for (auto &row : matrix)
{
row.resize(width);
}
}
Hope it helps!
Base function must be virtual for runtime inheritance.
as follows example
class base {
public:
virtual void print()
{
cout << "print base class\n";
}
void show()
{
cout << "show base class\n";
}
};
class derived : public base {
public:
void print()
{
cout << "print derived class\n";
}
void show()
{
cout << "show derived class\n";
}
};
int main()
{
base *bptr;
derived d;
bptr = &d;
// Virtual function, binded at runtime
bptr->print();
// Non-virtual function, binded at compile time
bptr->show();
return 0;
}
App.h:
#ifndef APP_H
#define APP_H
#include <SFML/Graphics.hpp>
#include <vector>
#include "RoomManager.h"
typedef unsigned int uint;
class App {
private:
sf::RenderWindow window;
sf::Event evt;
uint screen_width = 0;
uint screen_height = 0;
sf::Clock deltaClock;
float deltaTime = 0.0f;
RoomManager& roomManager = RoomManager::GetInstance();
std::vector<sf::Sprite> allDrawables;
App() { }
~App() { }
public:
static App& GetInstance() {
static App instance;
return instance;
}
void CreateWindow(uint width, uint height) {
screen_width = width;
screen_height = height;
window.create(sf::VideoMode(screen_width, screen_height), "Point'n'click adventure");
}
void Update() {
while (window.isOpen()) {
deltaTime = deltaClock.restart().asSeconds();
while (window.pollEvent(evt)) {
if (evt.type == sf::Event::EventType::Closed)
window.close();
}
Draw();
}
}
void ResizeScreen(uint width, uint height) {
screen_width = width;
screen_height = height;
window.setSize(sf::Vector2u(screen_width, screen_height));
}
void AddDrawable(sf::Sprite& sprite) {
allDrawables.push_back(sprite);
}
void Draw() {
window.clear();
for (int i = 0; i < allDrawables.size(); i++) {
window.draw(allDrawables[i]);
}
window.display();
}
};
#endif
DrawableEntity.h:
#ifndef DRAWABLEENTITY_H
#define DRAWABLEENTITY_H
#include <SFML/Graphics.hpp>
#include "App.h"
class DrawableEntity {
private:
sf::Texture backgroundTexture;
sf::Sprite backgroundSprite;
public:
DrawableEntity() {
App::GetInstance().AddDrawable(backgroundSprite);
}
~DrawableEntity() { }
void LoadTexture(const std::string texturePath) {
backgroundTexture.loadFromFile(texturePath);
backgroundSprite.setTexture(backgroundTexture);
}
};
#endif
RoomManager.h:
#ifndef ROOMMANAGER_H
#define ROOMMANAGER_H
#include <SFML/Graphics.hpp>
#include <vector>
#include "Room.h"
class RoomManager {
private:
std::vector<Room> rooms;
public:
static RoomManager& GetInstance() {
static RoomManager instance;
return instance;
}
void AddRoom(Room room) {
rooms.push_back(room);
}
};
#endif
Room.h:
#ifndef ROOM_H
#define ROOM_H
#include <SFML/Graphics.hpp>
#include "App.h"
#include "DrawableEntity.h"
class Room {
private:
DrawableEntity background;
public:
Room(const std::string backgroundTexturePath) {
background.LoadTexture(backgroundTexturePath);
}
~Room() { }
};
#endif
main.cpp:
#include <SFML/Graphics.hpp>
#include "App.h"
using namespace sf;
int main() {
App& app = App::GetInstance();
RoomManager& roomManager = RoomManager::GetInstance();
app.CreateWindow(1920, 1080);
roomManager.AddRoom(Room("room_0_background.jpg"));
app.Update();
return 0;
}
My idea here is that whenever I would create DrawableEntity object, it would automatically add its sprite to allDrawables vector in App. The above code throws me C2653 error saying that "'App' is not a class or namespace name". The error appears in DrawableEntity() constructor, at line where I call AddDrawable() method. It's been a while since I coded in C++ (now I code mostly in C#) and I'm not sure how to fix this.
[Note: As, you haven't shared DrawableEntity() constructor code(I didn't find any) I am assuming your problem might be the following. If the following solution does not solve your issue, please share DrawableEntity() constructor code.]
You must have called AddDrawable() as following:
App& appInstance = App::GetInstance();
appInstance::AddDrawable(); // it is wrong
You shouldn't call like above
Rather do the following:
App& appInstance = App::GetInstance();
appInstance.AddDrawable(); // it is correct
Edit(Possible solution, this must be happening in your code):
I guess #drescherjm is right. Please, take a careful look at the code snippets below. I have tested some codes similiar like your code structure:
so_test.cpp file:
#include <cstdio>
#include "so_header.h"
int main() {
A& objA = A::getInstance();
int xa = objA.getX();
printf("xa: %d\n", xa);
B& objB = B::getInstance();
int xb = objB.getX();
printf("xb: %d\n", xb);
return 0;
}
so_header.h file:
#ifndef CLASS_A
#define CLASS_A
#include <cstdio>
#include "so_header_2.h"
class A {
private:
int x = 100;
A(){}
public:
static A& getInstance() {
static A obj;
return obj;
}
int getX() {
return x;
}
void print() {
B& objB = B::getInstance();
int xb = objB.getX();
printf("xb: %d\n", xb);
}
};
#endif
so_header_2.h:
#ifndef CLASS_B
#define CLASS_B
#include <cstdio>
#include "so_header.h"
class B {
private:
int x = 200;
B(){}
public:
static B& getInstance() {
static B obj;
return obj;
}
int getX() {
return x;
}
void print() {
A& objA = A::getInstance();
int xa = objA.getX();
printf("xa: %d\n", xa);
}
};
#endif
When I compile so_test.cpp, I get the follwowing error(using mingw compiler):
In file included from so_header.h:6:0,
from so_test.cpp:2:
so_header_2.h: In member function 'void B::print()':
so_header_2.h:21:3: error: 'A' was not declared in this scope
A& objA = A::getInstance();
^
so_header_2.h:21:6: error: 'objA' was not declared in this scope
A& objA = A::getInstance();
^
so_header_2.h:21:13: error: 'A' is not a class, namespace, or enumeration
A& objA = A::getInstance();
The reason is in print function of A, A is calling B and in print function of B, B is calling A.
Your code structure follows a similiar pattern. Let's start from DrawableEntity.
> DrawableEntity calls App
> App calls RoomManager
> RoomManager calls Room
> Room calls App and DrawableEntity(notice, the order here. App is called before DrawableEntity, and so loop has come back to App)
> App calls RoomManager...and ...so on...
So, the loop is:
DrawableEntity -> App -> RoomManager -> Room -> App -> RoomManager -> ...
As, App is the start of the loop or the first object in the loop to be called, you're getting error recognizing "App" class...cause, you started declaring App, but you've never finished declaring it, and in the middle of declaring it, you are trying to use it. So, you're basically trying to use something that hasn't even seen the light of existence(An analogy could be: its still in womb, not born yet...).
This has happended with your code.
To solve your problem, you need to reorganize your code structure a bit. Just break the cycle(i.e. loop) of call dependency, and you'd be okay.
I moved from compiling my code in gcc to the compiler provided by Visual Studio 2017.
Every time I try to run the application I get the following error:
Here is the file where I believe the error is coming from:
Texture.h
#include <SDL2/SDL.h>
#include <memory>
#include <string>
namespace AcsGameEngine {
class Renderer;
class Texture {
public:
Texture(const Renderer& renderer);
Texture(const Renderer& renderer, const std::string&);
Texture(const Texture& orig) = default;
virtual ~Texture();
void load(const std::string&, uint16_t w = 0, uint16_t h = 0) const;
void load(const char*, uint16_t w = 0, uint16_t h = 0);
const Renderer& getRenderer() const { return m_renderer; }
//inline SDL_Texture* getRawPointer() const { return m_texture->get(); }
private:
std::unique_ptr<SDL_Texture> m_texture;
const Renderer& m_renderer;
uint16_t m_width;
uint16_t m_height;
};
} // namespace AcsGameEngine
Texture.cpp
#include "Texture.h"
#include "Renderer.h"
#include <SDL2/SDL_image.h>
namespace AcsGameEngine {
Texture::Texture(const Renderer &renderer) : m_renderer(renderer) {
}
Texture::Texture(const Renderer &renderer, const std::string &p) : Texture(renderer) {
load(p.c_str());
}
Texture::~Texture() {
if (m_texture != nullptr) {
SDL_DestroyTexture(m_texture.get());
}
}
void Texture::load(const std::string &path, uint16_t w, uint16_t h) const {
load(path.c_str());
}
void Texture::load(const char *path, uint16_t w, uint16_t h) {
SDL_Surface *tmp = IMG_Load(path);
m_texture.reset(SDL_CreateTextureFromSurface(m_renderer.getRawPointer(), tmp));
SDL_FreeSurface(tmp);
if (m_texture == false) {
//error
}
}
} // namespace AcsGameEngine
I don't understand why it is complaining of an undefined type because SDL.h contains the struct SDL_Texture.
SDL.h does not contain the definition of SDL_Texture. It only contains a forward declaration for it. This is because you are never meant to use the type directly, you are only ever meant to use pointers to it. However, in order to instantiate std::unique_ptr<SDL_Texture>, you need the full definition.
But why are you using a std::unique_ptr without a custom deleter here anyway, since you just have to manually delete the object with SDL_DestroyTexture? That defeats the whole purpose of using a smart pointer. Try this:
struct TextureDeleter
{
void operator()(SDL_Texture* tp) {
SDL_DestroyTexture(tp);
}
};
std::unique_ptr<SDL_Texture, TextureDeleter> m_texture;
SDL_Texture structure is not declared in SDL.h. It is an internal type and only its forward declaration is available in public interfaces, you can not delete it. You should provide the custom deleter to the smart pointer std::unique_ptr<SDL_Texture, void(SDL_Texture*)> m_texture and assign later m_texture = std::unique_ptr(SDL_CreateTextureFromSurface(...), SDL_DestroyTexture).
Basically for some reason new object is wrong type. All source code is on github https://github.com/teuro/sfml-radar. If it's help please fork at will.
I have following class:
#ifndef _VIEW_HPP
#define _VIEW_HPP
#include <iostream>
#include "sfml_drawsurface.hpp"
class View {
protected:
View(Drawsurface& d) : drawer(d) {
std::clog << "View::View()" << std::endl;
}
Drawsurface& drawer;
virtual void draw() = 0;
};
#endif
That is base class for all different kind of views. Now I have derived sub-class
#ifndef _GAME_VIEW_HPP
#define _GAME_VIEW_HPP
#include <vector>
#include <iostream>
#include <typeinfo>
#include "view.hpp"
#include "../models/game.hpp"
class Gameview : public View {
public:
Gameview(Drawsurface& d);
~Gameview();
void draw();
private:
Drawsurface& drawer;
};
#endif // _GAME_VIEW_HPP
Then abstract class Drawsurface
/**
* drawsurface base for all graphics pure abstract
* provide only interface quite high-level
* 2014/06/02
* Juha Teurokoski
**/
#ifndef _DRAWSURFACE_HPP
#define _DRAWSURFACE_HPP
#include <string>
#include "../models/point.hpp"
class Drawsurface {
public:
bool font_loaded;
virtual void rectangleColor(Point& a, Point& b, unsigned int color) = 0;
virtual void lineColor(Point& a, Point& b, unsigned int color) = 0;
virtual void circleColor(Point& a, unsigned int rad, unsigned int color) = 0;
virtual void trigonColor(Point& a, Point& b, Point& c, unsigned int color) = 0;
virtual void trigonColor(Point& a, unsigned int size, unsigned int color) = 0;
virtual void load_font(std::string font) = 0;
virtual void draw_picture(std::string tiedosto, Point& a, bool center = false) = 0;
virtual void draw_text(std::string text, Point& a, unsigned int color = 0) = 0;
virtual int get_fontsize() = 0;
virtual void flip() = 0;
virtual void clear_screen() = 0;
virtual ~Drawsurface() { }
};
#endif
Now if I create new instance of sfml_drawsurface which is sub-class of Drawsurface. For some reason new object is Drawsuface istead of sfml_drawsurface. Below is sfml_drawsurface class.
#ifndef SFML_DRAWSURFACE_HPP
#define SFML_DRAWSURFACE_HPP
/**
* sfml-drawsurface provides basic drawing, pictures and text
* require drawsurface
* 2014/06/02
* Juha Teurokoski
**/
#include "drawsurface.hpp"
#include <vector>
#include <stdexcept>
#include <iostream>
#include <SFML/Graphics.hpp>
class sfml_drawsurface : public Drawsurface {
public:
sfml_drawsurface(sf::RenderWindow& window);
~sfml_drawsurface();
void rectangleColor(Point& a, Point& b, unsigned int color);
void circleColor(Point& a, unsigned int rad, unsigned int color);
void lineColor(Point& a, Point& b, unsigned int color);
void trigonColor(Point& a, Point& b, Point& c, unsigned int color);
void trigonColor(Point& a, unsigned int _size, unsigned int color);
void draw_picture(std::string tiedosto, Point& a, bool center = false);
void draw_text(std::string text, Point& a, unsigned int color);
void load_font(std::string font);
void clear_screen();
int get_fontsize();
void flip();
protected:
private:
sf::RenderWindow& window;
sf::Font font;
sf::Color active;
sf::Color normal;
};
#endif // SFML_DRAWSURFACE_HPP
I create new object like this:
sfml_drawsurface drawer(window);
this->gameview = new Gameview(drawer);
std::clog << typeid(drawer).name() << std::endl;
And everything seems to be right, because std::clog outout is '16sfml_drawsurface'.
Next place is draw-method then happens something really weird.
Same print is now '11Drawsurface'.
Looks like Mike had the right idea. From your Program.cpp file you have in your constructor:
Program::Program() {
Game game;
...
this->gamecontroller = new Gamecontroller(game); //Probably also bad
sfml_drawsurface drawer(window);
this->gameview = new Gameview(drawer);
}
The problem is that drawer ceases to exist once the constructor is finished leaving you with a dangling reference and undefined behaviour. Looks like you may have the same problem with the game variable.
Solution is to not have them as local variables but as either class members (preferred) or dynamically allocated (it depends how long you need to have them around).
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am working on my own GUI framework using C++ and OpenGL. My experience in both is small as this is my first project using them.
In the framework I have created a window, which renders the design of the window, and then any objects that have been added to the window as a child.
I then create the window using a new class called MainMenu that inherits from my window class, I then add a new button to the MainMenu
Using:
button->SetOnClick(&MainMenu::button_Click, this);
I then add a pointer to the function, as well as the instance of the class to the buttons 'SetOnClick' method - Therefore if that button is clicked a method within the MainMenu will run.
This works great at the moment, however my issue now is that I want to add a new window called Settings, which will also inherit from the Window class
Therefore I need to make the function pointer in my button class work for any number of classes (all of type Window)
Here is the code that is currently working - but for only the MainMenu (Please note that I have stripped out a lot of methods that do not relate to the question to make it easier to read)
Window.h:
class Window
{
private:
void Initialize(WindowManager* manager, int width, int height);
public:
Window(WindowManager* manager);
Window(WindowManager* manager, int width, int height);
~Window(void);
void Render();
bool MouseMove(int x, int y);
bool MouseLBDown(int x, int y);
Children* Child() { return m_children; };
MainMenu.h:
class MainMenu : public ObjWindow
{
private:
void Initialize();
public:
MainMenu(WindowManager* manager, int width, int height) : Window(manager, width, height)
{
Initialize();
};
MainMenu(WindowManager* manager) : Window(manager)
{
Initialize();
};
~MainMenu(void);
void button_Click();
MainMenu.cpp:
void MainMenu::Initialize()
{
Button* button = new Button(Vector2D(100, -400), 100, 50);
Child()->Add(button);
button->SetText("Click Me!");
button->SetOnClick(&MainMenu::button_Click, this);
}
void MainMenu::button_Click()
{
//Do some button code
}
Button.h:
class Button
{
typedef void (MainMenu::*Function)();
Function m_onClickFunction;
MainMenu* m_window;
public:
Button(Vector2D position, int width, int height);
~Button(void);
void SetText(std::string);
std::string GetText();
void Render();
bool MouseMove(int x, int y);
bool MouseLBDown(int x, int y);
void SetOnClick(Function, MainMenu*);
Button.cpp:
Button::Button(Vector2D position, int width, int height)
{
m_onClickFunction = NULL;
}
Button::~Button(void)
{
}
bool Button::MouseMove(int x, int y)
{
return true;
}
bool Button::MouseLBDown(int x, int y)
{
if (m_body->Intercepts(x,y))
{
if (m_onClickFunction != NULL)
{
(m_window->*m_onClickFunction)();
}
}
return true;
}
void Button::SetOnClick(Function function, MainMenu* window)
{
m_onClickFunction = function;
m_window = window;
}
From researching around the internet it seems that I need to use a template so that I can handle the class as a type, I have tried fitting this in to my code, but so far I nothing has worked.
Please note that I am also new to asking question on stackoverflow, so if I am missing anything important please let me know
You need to either create a template of the Button class - in your case it would look like this:
template <typename myType>
class Button{
typedef void (myType::*Function)();
Function m_onClickFunction;
myType* m_window;
public:
...
void SetOnClick(Function, myType*);
}
And use it like this:
Button<MainMenu> button;
button->SetOnClick(&MainMenu::button_Click, this);
...or create a delegate class. There are plenty of examples about delegates in C++, if you search for them.
But I'm not so sure if you wan't to stick with passing pointers to functions. You might be better off always calling the same method of derived classes, and using the virtual keyword.
Like this:
class Window{
public:
virtual void button_Click(){};
};
class someDerivedWindow: public Window{
public:
void button_Click(){};
};
and inside the button class just calling:
m_window->button_Click();
You could work and implement your own library to do member function pointers, depending on what the goal of your project is. It is fairly complicated though, and requires a rather deep understanding of C++.
However, you can also use boost::function combined with std::bind or boost:bind, to achieve what you want to do.
If you have
struct X {
int foo(int);
};
You can use:
boost::function1<int, int> f;
X x;
f = std::bind1st(
std::mem_fun(&X::foo), &x);
f(5); // Call x.foo(5)
This example is taken directly from the boost::function documentation - http://www.boost.org/doc/libs/1_55_0/doc/html/function.html
If using C++11:
#include <iostream>
#include <functional>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <ctime>
using namespace std;
int foo1()
{
return 0;
}
int foo2()
{
return 1;
}
int main()
{
function<int()> f1 = foo1;
function<int()> f2 = foo2;
//do some magic
srand(time(0));
function<function<int()>()> generator = [&]()
{
if(rand() % 2 == 0)
return foo1;
else
return foo2;
};
vector<function<int()>> vec(100);
generate(vec.begin(),vec.end(),generator);
for(auto elem: vec)
cout << elem() << endl;
return 0;
}