Can not call function pointer of a struct to a class method - c++

use C++98. I have a struct t_fd which is used inside a class MS. In the struct there are two pointers to function: fct_read, fct_write. I designed that the function pointers are pointing to the two methods of the class. But then I have this error when trying to call them.
expression preceding parentheses of apparent call must have (pointer-to-) function type.
Please advice on the error, also on the design. I need the two functions are methods of that class because I need to use class's attributes (even though it isn't showed here for the shake of simplicity). Thank you for your time, I appreciate your help!
#include <vector>
#include <iostream>
typedef struct s_fd {
void(MS::*fct_read) (int);
void(MS::*fct_write) (int);
} t_fd;
class MS
{
private:
std::vector< t_fd > _fdSet;
void server_accept(int s)
{
if (s % 2 == 0)
_fdSet[cs].fct_read = MS::client_read;
else
_fdSet[cs].fct_write = MS::client_write;
}
void client_read(int fd)
{
std::cout << "I'm reading\n";
}
void client_write(int fd)
{
std::cout << "I'm writing\n";
}
void check_fd()
{
int i = 0;
int size = 10;
while (i < size)
{
if (i < 5)
_fdSet[i].fct_read(i); //Error here!
if (i >= 5)
_fdSet[i].fct_write(i); //Error here!
i++;
}
}
};

The intent of your code is difficult to understand (in its current form). But I would be happy to solve few issues in your code.
MS class needs to be declared before you reference it the type from s_fd structure definition :
class MS; // forward declaration
typedef struct s_fd {
void(MS::* fct_read) (int);
void(MS::* fct_write) (int);
} t_fd;
class MS
{ ... }
the syntax to assign function pointer is incorrect. You forgot &:
_fdSet[cs].fct_read = &MS::client_read;
fct_read and fct_write are member function pointers. They should be applied on instance of MS class. In case you want to apply them on this object:
if (i < 5) {
auto fptr = _fdSet[i].fct_read;
(this->*fptr)(i);
}

Related

Template Return c++

I am trying to switch between two class objects based on a global variable DOF. The idea is to change the return type using the template class. But the first line inside main() has a compile-time error template argument deduction/substitution failed. Could you please help me to understand the problem and fix it and is there a better way of doing this? Any suggestions and help are appreciated. Thanks in advance.
#include <iostream>
#include <string>
class MM
{
public:
MM(){}
std::string printName()
{
return "MM";
}
};
class MM2
{
public:
MM2(){}
std::string printName()
{
return "MM2";
}
};
using namespace std;
const unsigned short int DOF = 7;
MM* obj = nullptr;
MM2* obj2 = nullptr;
template<class T>
T getClass()
{
if(DOF==7)
{
if(obj == nullptr)
{
obj = new MM();
}
return obj;
}
else if(DOF == 6)
{
if(obj2 == nullptr)
{
obj2 = new MM2();
}
return obj2;
}
}
int main()
{
getClass()->printName();
//std::cout << "class name " << getClass()->printName() << std::endl;
return 0;
}
That is not how templates work in C++. The type of the template parameter must be known at compile time and cannot change at runtime.
The pattern you are trying to achieve in your example scan easily be done with virtual functions: make MM and MM2 have a common base class and make printName a virtual function. While we are here: don't use manual memory management, i.e. don't use explicit new/delete. Use smart pointers like unique_ptr.
Other options are std::any and std:: variant but I wouldn't recommend them unless you have a very particular use case for them.
For your simple example an option could be to return a function pointer or a std::function. That would work on your example because your classes are stateless, but I suspect your real classes have state or more methods you wish to access in which case you shouldn't try to do this.
If you can use C++17 (and if you can't then that's a shame), you can do this if you switch things round a bit.
Firstly, use a template parameter to determine what getClass does and use if constexpr instead of just plain old if:
template<int N>
auto getClass()
{
if constexpr (N == 7)
{
if(obj == nullptr)
{
obj = new MM();
}
return obj;
}
else if constexpr (N == 6)
{
if(obj2 == nullptr)
{
obj2 = new MM2();
}
return obj2;
}
}
Then invoke this template like this:
std::cout << "class name " << getClass <DOF> ()->printName() << std::endl;
Miscellaneous notes:
All paths through getClass should return a value.
You are leaking memory by calling new and not calling delete. Better options are available.
Edit: Here's a C++11 solution using SFINAE:
template<int N, typename std::enable_if<N == 7, int>::type = 0>
MM *getClass()
{
if(obj == nullptr)
{
obj = new MM();
}
return obj;
}
template<int N, typename std::enable_if<N == 6, int>::type = 0>
MM2 *getClass()
{
if(obj2 == nullptr)
{
obj2 = new MM2();
}
return obj2;
}
And then you can still do:
std::cout << "class name " << getClass <DOF> ()->printName() << std::endl;
Live demo
This is something you might try. As others have said, templates only work at compile time: if you want to dynamically change the types later during runtime, then polymorphism is the way to go. You can use a kind of 'PIMPL' design to effectively 'insert' a base class above the MM and MM2 classes. The base class includes pure virtual functions for all the common functions for MM and MM2 that you need to access (eg printName() in this example).
#include <iostream>
#include <memory>
#include <string>
class MM
{
public:
MM() {}
std::string printName()
{
return "MM";
}
};
class MM2
{
public:
MM2() {}
std::string printName()
{
return "MM2";
}
};
class MMBase
{
public:
virtual std::string printName() = 0;
virtual ~MMBase() {}
};
//Templated wrapper for each MM class type, deriving from abstract MMBase
template<class T>
class MMWrap : public MMBase
{
std::unique_ptr<T> _impl;
public:
MMWrap() : _impl(nullptr)
{
_impl = std::make_unique<T>();
}
//Pass function call to _impl pointer
std::string printName()
{
return _impl->printName();
}
};
class MMFactory
{
public:
enum MMType {TypeMM2=6,TypeMM};
static MMType _type;
static std::unique_ptr<MMBase> getMM()
{
if (_type == TypeMM) return std::unique_ptr<MMBase>(new MMWrap<MM>());
if (_type == TypeMM2) return std::unique_ptr<MMBase>(new MMWrap<MM2>());
return nullptr; //Avoids compiler warning about not all paths return value
}
};
//Initialize static member to which default MM type is required
MMFactory::MMType MMFactory::_type = MMFactory::TypeMM;
int main()
{
std::cout<< MMFactory::getMM()->printName() << std::endl;
MMFactory::_type = MMFactory::TypeMM2;
std::cout << MMFactory::getMM()->printName() << std::endl;
}
I've put in a templated wrapper class, but that may need modification depending what parameters the MM/MM2 constructors need. Also the wrapped pointers are created within the constructor (if they throw then there might be an issue): these could be moved to a lazy evaluation model, making _impl mutable. I don't know how MM/MM2 are used later: if they have functions which take references to other MM types then a bit more work may be needed.

std::find return a class that I can't acesses functions

I come from C/C# language and now I'm trying to learn about C++ and his standards functions.
Now, I'm creating a class called IMonsterDead. I will have a std::vector<IMonsterDead*> with N monsters.
Example:
class IMonsterDead {
public:
IMonsterDead(int Id)
{
this->_Id = Id;
}
virtual void OnDead() = 0;
int Id() const {
return _Id;
}
private:
int _Id;
};
One class which implements that class:
class MonsterTest : public IMonsterDead {
public:
MonsterTest(int generId)
: IMonsterDead(generId)
{
}
virtual void OnDead()
{
std::cout << "MonsterTesd died" << std::endl;
}
};
Ok, if I access directly everything works fine. But I'm trying to use std::find.
Full program test:
int main()
{
std::vector<IMonsterDead*> monsters;
for (int i = 0; i < 1000; i++)
{
monsters.emplace_back(new MonsterTest(1000 + i));
}
int id = 1033;
std::vector<IMonsterDead*>::iterator result = std::find(monsters.begin(), monsters.end(), [id]( IMonsterDead const* l) {
return l->Id() == id;
});
if (result == monsters.end())
std::cout << "Not found" << std::endl;
else
{
// Here I want to access OnDead function from result
}
return 0;
}
So I need to access OnDead function from result but I can't. Intellisense doesn't show anything for me. The result exists.
How can I access that function? Have another better way to do that?
You need to use std::find_if() instead of std::find(). std::find() is for finding an element with a specific value, so you have to pass it the actual value to find, not a user_defined predicate. std::find_if() is for finding an element based on a predicate.
Either way, if a match is found, dereferencing the returned iterator will give you a IMonsterDead* pointer (more accurately, it will give you a IMonsterDead*& reference-to-pointer). You need to then dereference that pointer in order to access any members, like OnDead().
You are also leaking memory. You are not delete'ing the objects you new. And when dealing with polymorphic types that get deleted via a pointer to a base class, the base class needs a virtual destructor to ensure all derived destructors get called properly.
With that said, you are clearly using C++11 or later (by the fact that you are using vector::emplace_back()), so you should use C++11 features to help you manage your code better:
You should use std::unique_ptr to wrap your monster objects so you don't need to delete them manually.
You should always use the override keyword when overriding a virtual method, to ensure you override it properly. The compiler can catch more syntax errors when using override than without it.
You should use auto whenever you declare a variable that the compiler can deduce its type for you. Especially useful when dealing with templated code.
Try something more like this:
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
class IMonsterDead {
public:
IMonsterDead(int Id)
: m_Id(Id)
{
}
virtual ~IMonsterDead() {}
virtual void OnDead() = 0;
int Id() const {
return m_Id;
}
private:
int m_Id;
};
class MonsterTest : public IMonsterDead {
public:
MonsterTest(int generId)
: IMonsterDead(generId)
{
}
void OnDead() override
{
std::cout << "MonsterTest died" << std::endl;
}
};
int main()
{
std::vector<std::unique_ptr<IMonsterDead>> monsters;
for (int i = 0; i < 1000; i++)
{
// using emplace_back() with a raw pointer risks leaking memory
// if the emplacement fails, so push a fully-constructed
// std::unique_ptr instead, to maintain ownership at all times...
monsters.push_back(std::unique_ptr<IMonsterDead>(new MonsterTest(1000 + i)));
// or:
// std::unique_ptr<IMonsterDead> monster(new MonsterTest(1000 + i));
// monsters.push_back(std::move(monster));
// or, if you are using C++14 or later:
// monsters.push_back(std::make_unique<MonsterTest>(1000 + i));
}
int id = 1033;
auto result = std::find_if(monsters.begin(), monsters.end(),
[id](decltype(monsters)::value_type &l) // or: (decltype(*monsters.begin()) l)
{
return (l->Id() == id);
}
// or, if you are using C++14 or later:
// [id](auto &l) { return (l->Id() == id); }
);
if (result == monsters.end())
std::cout << "Not found" << std::endl;
else
{
auto &monster = *result; // monster is 'std::unique_ptr<IMonsterDead>&'
monster->OnDead();
}
return 0;
}
Iterators are an interesting abstraction, in this case to be reduced to pointers.
Either you receive the pointer to the element or you get an invalid end.
You can use it as a pointer: (*result)->func();
You can also use it to create a new variable:
IMonsterDead &m = **result;
m.func();
This should give the same assembly, both possible.

c ++ Class Method Pointer as Function Argument

I am trying to create a dynamic function pointer that points to some methods all the methods I want to save on the array return a bool and have an uint32_t parameter. The functions are Service functions. These are intended to be dynamic, so when a class is started, the constructor links the service function from the object to be called from outside the object.
With the code below I am getting the following error:
Build error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.
I have no clue what to do to overcome this problem, any idea would be greatly appreciated, thanks!
//File 1
typedef bool (*ServiceFunctionsType)(uint32_t);
//File 2
#include "File1.hpp"
extern uint8_t ServiceFunctions_size;
extern ServiceFunctionsType *ServiceFunctions;
void Service_Functions_Setup();
bool SetPtr(ServiceFunctionsType a);
void ClearPtr(uint8_t id);
//File 3
#include "File1.hpp"
ServiceFunctionsType *ServiceFunctions;
uint8_t ServiceFunctions_size = 0;
//File 4
#include "File2.hpp"
#include <stdlib.h>
void Service_Functions_Setup()
{
ServiceFunctions = NULL;
if(SERVICE_FUNCTION_POINTER_START_SIZE != 0)
{
ServiceFunctions_size = SERVICE_FUNCTION_POINTER_START_SIZE;
ServiceFunctions = (ServiceFunctionsType*)malloc(sizeof(ServiceFunctionsType)*SERVICE_FUNCTION_POINTER_START_SIZE);
for(uint8_t i = 0; i < SERVICE_FUNCTION_POINTER_START_SIZE; i++)
{
ServiceFunctions[i] = NULL;
}
}
}
uint8_t SetServiceFunctionPointer(ServiceFunctionsType a, bool _realloc)
{
if( ServiceFunctions == NULL )
{
ServiceFunctions = (ServiceFunctionsType*)malloc(sizeof(ServiceFunctionsType));
ServiceFunctions[0] = a;
return 0;
}
for(uint8_t i = 0; i < ServiceFunctions_size; i++)
{
if( ServiceFunctions[i] == NULL )
{
ServiceFunctions[i] = a;
return i;
}
}
if(_realloc)
{
ServiceFunctions_size++;
ServiceFunctions = (ServiceFunctionsType*)realloc(ServiceFunctions,sizeof(ServiceFunctionsType)*ServiceFunctions_size);
ServiceFunctions[ServiceFunctions_size - 1] = a;
return ServiceFunctions_size - 1;
}
return INVALID_SERVICE_FUNCTION_POINTER;
}
void ClearServiceFunctionPointer(uint8_t id)
{
ServiceFunctions[id] = NULL;
}
//File 5
class MonoStepSequencer
{
public:
MonoStepSequencer();
~MonoStepSequencer();
uint8_t ServicePointerID;
bool Service(uint32_t time);
private:
};
//File 6
#include "File2.hpp"
MonoStepSequencer::MonoStepSequencer()
{
ServicePointerID = SetServiceFunctionPointer(&this -> Service);
}
//This is the function to be called with a pointer
bool MonoStepSequencer::Service(uint32_t time)
{
//Some Code
}
You can try, to use lambdas. Create method like
std::function<void()> getService()
Where inside you can use:
return [this](){
Service();
};
Also if your methods should use arguments, you can use this method, but add arguments into return value and lambda.
One more, you can create lambda outside of class methods, like:
[&object]()
{
object.Service();
}
In this way, better to use std::shared_ptr to guŠ°rantee that object exists, when lambda called.
this -> Service is an unqualified or parenthesized non-static member function
You probably meant :: instead of -> Also, you need a type on the left, not a variable.
Also, please don't put spaces around ->. That makes it look like you're specifying a trailing return type or something.

Non-pointer member function typedefs in C++?

I'd like to be able to use a single C++ typedef for both member function declarations and for pointers to them used elsewhere. If I could match the structure of non-member functions like the following, it would be perfect:
#include <iostream>
using x_ft = char (int);
// Forward decls both advertise and enforce shared interface.
x_ft foo, bar;
char foo(int n) { return (n % 3 == 0) ? 'a' : 'b'; }
char bar(int n) { return (n % 5 == 0) ? 'c' : 'd'; }
int main(int argc, char *argv[]) {
// Using same typedef for pointers as the non-pointers above.
x_ft *f{foo};
x_ft *const g{(argc % 2 == 0) ? bar : foo};
std::cout << f(argc) << ", " << g(argc * 7) << std::endl;
}
I don't seem to be able to avoid type quasi-duplication for non-static member functions though:
struct B {
// The following works OK, despite vi_f not being class-member-specific.
using vi_ft = void(int);
vi_ft baz, qux;
// I don't want redundant definitions like these if possible.
using vi_pm_ft = void(B::*)(int); // 'decltype(&B::baz)' no better IMO.
};
void B::baz(int n) { /* ... */ }
void B::qux(int n) { /* ... */ }
void fred(bool x) {
B b;
B::vi_pm_ft f{&B::baz}; // A somehow modified B::vi_f would be preferable.
// SYNTAX FROM ACCEPTED ANSWER:
B::vi_ft B::*g{x ? &B::baz : &B::qux}; // vi_ft not needed in B:: now.
B::vi_ft B::*h{&B::baz}, B::*i{&B::qux};
(b.*f)(0);
(b.*g)(1);
(b.*h)(2);
(b.*i)(3);
}
My actual code can't really use sidesteps like "auto f = &B::foo;" everywhere, so I'd like to minimize my interface contracts if at all possible. Is there a valid syntax for naming a non-pointer member function type? No trivial variants of void(B::)(int), void(B::&)(int), etc. work.
Edit: Accepted answer - the func_type Class::* syntax is what I was missing. Thanks, guys!
The syntax you seem to be looking for is vi_ft B::*f.
using vi_ft = void(int);
class B {
public:
vi_ft baz, qux;
};
void B::baz(int) {}
void B::qux(int) {}
void fred(bool x) {
B b;
vi_ft B::*f{ x ? &B::baz : &B::qux };
(b.*f)(0);
}
int main() {
fred(true);
fred(false);
}
Above code at coliru.

How to pass a function to a function?

Suppose I have a class with 2 static functions:
class CommandHandler
{
public:
static void command_one(Item);
static void command_two(Item);
};
I have a DRY problem where I have 2 functions that have the exact same code for every single line, except for the function that it calls:
void CommandOne_User()
{
// some code A
CommandHandler::command_one(item);
// some code B
}
void CommandTwo_User()
{
// some code A
CommandHandler::command_two(item);
// some code B
}
I would like to remove duplication, and, ideally, do something like this:
void CommandOne_User()
{
Function func = CommandHandler::command_one();
Refactored_CommandUser(func);
}
void CommandTwo_User()
{
Function func = CommandHandler::command_one();
Refactored_CommandUser(func);
}
void Refactored_CommandUser(Function func)
{
// some code A
func(item);
}
I have access to Qt, but not Boost. Could someone help suggest a way on how I can refactor something like this?
You could use function pointers:
// type of the functions
typedef void Function(Item);
void CommandOne_User() {
// function pointer
Function *func = CommandHandler::command_one;
Refactored_CommandUser(func);
}
void CommandTwo_User() {
// can also be used directly, without a intermediate variable
Refactored_CommandUser(CommandHandler::command_two);
}
// taking a function pointer for the command that should be executed
void Refactored_CommandUser(Function *func) {
// calling the funcion (no explicit dereferencing needed, this conversion is
// done automatically)
func(item);
}
Besides the C way (passing a function pointer) or the C++ way mentioned by Jay here there is the other (modern) c++ way with boost or with a compiler with c++0x support:
void Refactored_CommandUser( boost::function<void (Item)> f ) {
// alternatively std::function with proper compiler support
}
With the advantage that this encapsulates a functor, and can be combined with boost::bind (or std::bind) to pass in not only free-function pointers that match the signature exactly, but also other things, like member pointers with an object:
struct test {
void f( Item );
};
void foo( Item i, std::string const & caller );
void bar( Item i );
int main() {
test t;
Refactored_CommandUser( boost::bind( &test::f, &t, _1 ) );
Refactored_CommandUser( boost::bind( foo, _1, "main" ) );
Refactored_CommandUser( bar ); // of course you can pass a function that matches directly
}
I posted a question very similar to this and this was the explanation I got:
Function Pointers
And here is the link to the question I posted: Function callers (callbacks) in C?
Another way to do this if you don't have access to tr1 or boost, is just to use function template. It's quite simple and obviously a C++ way.
Here's a compilable example similar to yours:
#include <iostream>
using namespace std;
class CommandHandler
{
public:
static void command_one(int i) { cout << "command_one " << i << endl; }
static void command_two(int i) { cout << "command_two " << i << endl; }
};
template <typename Func>
void CommandCaller(Func f)
{
f(1);
}
int main()
{
CommandCaller(&CommandHandler::command_one);
return 0;
}
I can think of two ways.
The C style way: pass the function to be called in as a function pointer.
The C++ way: create a base class that implements your code and replace the called function with a virtual method. Then derive two concrete classes from the base class, each one implementing the virtual function differently.
see this please
http://www.newty.de/fpt/fpt.html
Static member functions can be passed simply as function pointers.
Non-static can be passed as member-function pointer + this.
void Refactored_CommandUser(static void (*func)(Item))
{
// some code A
func(item);
// some code B
}
void CommandOne_User()
{
Refactored_CommandUser(&CommandHandler::command_one);
}
void CommandTwo_User()
{
Refactored_CommandUser(&CommandHandler::command_two);
}
So inspired by David Roriguez's answer, I tried it out on my own and, yup, it works:
Here's an example (stupid) code of the "modern" way to pass a function as a function parameter:
#include <functional>
#include <assert.h>
class Command
{
public:
static int getSeven(int number_)
{
return 7 + number_;
}
static int getEight(int number_)
{
return 8 - number_;
}
};
int func(std::tr1::function<int (int)> f, int const number_ )
{
int const new_number = number_ * 2;
int const mod_number = f(new_number);
return mod_number - 3;
}
int main()
{
assert( func(Command::getSeven, 5) == 14 );
assert( func(Command::getEight, 10) == -15 );
return 0;
}
I tried this on VS2008 with Intel C++ Compiler 11.1 with C++0X support on (don't know if C++0x support is really needed since it's in TR1).