Pointer to member function - type

J

jrx

I've got my_error exception type, defined as:

class my_error : public std::runtime_error {
public:
my_error(const std::string& msg) : std::runtime_error(msg) {}
};

Then, I've got Wrapper class, that wraps my classes. I create it:

Wrapper<my_error> my_error_wrapper;
my_error_wrapper.addMethod(&my_error::what);

The template method addMethod looks like:

template <class T>
class Wrapper {
public:
[...]
template <class Result>
void addMethod(Result (T::*method)()) {
}
};

The problem is, that.. it doesn't work. It appears that, my_error::what
has the type
const char* (std::runtime_error::*)() const
not:
const char* (my_error::*)() const

Quite tricky, because std::runtime_error also derives what() from
std::exception.

Is there any way to give pointer to such method as an argument?
Except form:

template <class Result, class Base>
void addMethod(Result (Base::*method)()) {
STATIC_ASSERT(is_derived<Base,T>::value);
}

Another question:
Is it possible to obtain method type in some way like:
template <class Method>
void addMethod(Method m_ptr) {
}

I know there is something like "function type" used e.g. in
boost::signals to write:
boost::signal<void (const char*)> my_signal;
Is there something like that for methods?

thanks in advance ;)

JRX
 
K

kwikius

jrx said:
The problem is, that.. it doesn't work. It appears that, my_error::what
has the type
const char* (std::runtime_error::*)() const
not:
const char* (my_error::*)() const

Quite tricky, because std::runtime_error also derives what() from
std::exception.

Is there any way to give pointer to such method as an argument?

In the above I think you need to make the signature const e.g:

template <class T>
class Wrapper {
/*...*/
//###########################################
void addMethod(Result (T::*method)() const) {
//############################################
}
};

Unfortunately the error message is misleading. Try the above and the
function should be found in the base class.


To call it I think boost::function etc won't help. You could define
your own functor maybe like this:

#include <stdexcept>
#include <iostream>


template <typename Class>
struct what_functor{
Class* m_p_class;
const char* (Class::* m_pf)()const;
what_functor(Class * p_class_in, const char* (Class::*
pf_in)()const)
: m_p_class(p_class_in),m_pf(pf_in){}

const char* operator()()
{
return ( m_p_class->*(m_pf))();
}
};

class my_error : public std::runtime_error {
public:
my_error(const std::string& msg) : std::runtime_error(msg) {}

};


int main()
{
my_error e("something");
// need a class instance pointer and the member function pointer
// to init the functor
what_functor<my_error> func(&e,&my_error::what);

std::cout << func() <<'\n';
}

regards
Andy Little
 
J

jrx

kwikius said:
In the above I think you need to make the signature const e.g:

template <class T>
class Wrapper {
/*...*/
//###########################################
void addMethod(Result (T::*method)() const) {
//############################################
}
};

Unfortunately the error message is misleading. Try the above and the
function should be found in the base class.
Unfortunately it doesn't work either.
Such signature:

template <class Return>
void addMethod(Return (T::*method)()const ) {
}

Causes error:
error: no matching function for call to
To call it I think boost::function etc won't help. You could define
your own functor maybe like this:

#include <stdexcept>
#include <iostream>


template <typename Class>
struct what_functor{
Class* m_p_class;
const char* (Class::* m_pf)()const;
what_functor(Class * p_class_in, const char* (Class::*
pf_in)()const)
: m_p_class(p_class_in),m_pf(pf_in){}

const char* operator()()
{
return ( m_p_class->*(m_pf))();
}
};

class my_error : public std::runtime_error {
public:
my_error(const std::string& msg) : std::runtime_error(msg) {}

};


int main()
{
my_error e("something");
// need a class instance pointer and the member function pointer
// to init the functor
what_functor<my_error> func(&e,&my_error::what);

std::cout << func() <<'\n';
}

I know, it works, but why in my example it doesn't compile properly?
 
K

kwikius

jrx said:
I know, it works, but why in my example it doesn't compile properly?

It may be because your version has more template parameters and it
can't make asumptions therefore.. maybe someone will give a better
explanation. The following seems to give a similar message on gcc if
the DERIVED_OVERRIDE define is commented out. So you could try
overriding the what function in your derived class. Note also the
throw() part of the signature which seems to be required here.

#include <stdexcept>
#include <iostream>

//comment out the define causes fail
#define DERIVED_OVERRIDE
struct what_functor{
template <typename Class, typename R>
R operator()(Class * p_class, R (Class::* pf)()const)const
{
return ( p_class->*pf)();
}
};

class my_error : public std::runtime_error {
public:
my_error(const std::string& msg) : std::runtime_error(msg) {}
#ifdef DERIVED_OVERRIDE
const char * what() const throw()
{
return std::runtime_error::what();
}
#endif
};

int main()
{
my_error e("something");
what_functor func;

std::cout << func(&e,&my_error::what) <<'\n';
}

regards
Andy Little
 
J

jrx

kwikius said:
It may be because your version has more template parameters and it
can't make asumptions therefore.. maybe someone will give a better
explanation. The following seems to give a similar message on gcc if
the DERIVED_OVERRIDE define is commented out. So you could try
overriding the what function in your derived class. Note also the
throw() part of the signature which seems to be required here.

#include <stdexcept>
#include <iostream>

//comment out the define causes fail
#define DERIVED_OVERRIDE
struct what_functor{
template <typename Class, typename R>
R operator()(Class * p_class, R (Class::* pf)()const)const
{
return ( p_class->*pf)();
}
};

class my_error : public std::runtime_error {
public:
my_error(const std::string& msg) : std::runtime_error(msg) {}
#ifdef DERIVED_OVERRIDEsame case as in my code. But I think it should compile even if method what() isn't overridden.
const char * what() const throw()
{
return std::runtime_error::what();
}
#endif
};

int main()
{
my_error e("something");
what_functor func;

std::cout << func(&e,&my_error::what) <<'\n';
}

That's the same case as in my code. But I think it should compile even
1if method what() isn't overridden. I have no idea, why me_error::what
behaves in such a strange way. Any suggestions for generic addMethod
method declaration?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,124
Latest member
JuniorPell
Top