By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,136 Members | 1,021 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,136 IT Pros & Developers. It's quick & easy.

Pointer to member function - type

P: n/a
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_errormy_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
--
JRX --dev \dot jrx \at gmail \dot com
If the words "open source" get you more excited than
the words "free porn"...you might be a Game Developer.
Registered Linux user# 383163
Dec 21 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
jrx wrote:
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_errorfunc(&e,&my_error::what);

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

regards
Andy Little

Dec 22 '06 #2

P: n/a
jrx
kwikius wrote:
>
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
‘Wrapper<my_error>::addMethod(const char*std::runtime_error::*)()const)’

>

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_errorfunc(&e,&my_error::what);

std::cout << func() <<'\n';
}
I know, it works, but why in my example it doesn't compile properly?
--
JRX --dev \dot jrx \at gmail \dot com
If the words "open source" get you more excited than
the words "free porn"...you might be a Game Developer.
Registered Linux user# 383163
Dec 22 '06 #3

P: n/a
jrx wrote:
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

Dec 22 '06 #4

P: n/a
jrx
kwikius wrote:
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?

--
JRX --dev \dot jrx \at gmail \dot com
If the words "open source" get you more excited than
the words "free porn"...you might be a Game Developer.
Registered Linux user# 383163
Dec 22 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.