I'm trying to let the return type of doSomeMethod()
be the same as the operator()
in the base class but if it's declared as protected the compiler rejects the code with error: no type named 'type' in 'std::result_of'
. It works if it's public but i wonder if I could get it working for the protected case too since.
Here is simple code reproducing the error.
#include <type_traits>
class base
{
protected:
int operator()(){return 1;};
};
class child : private base
{
auto static doSomeMethod()
-> typename std::result_of<base()>::type
{
return 1;
}
};
EDIT:
Ok thanks Kerrek SB and Dietmar Kühlr for your solutions and explanations. After playing around with it I found this solution that is more readable and works (at least in my real case where child
is template class and base
one of its template parameters) more reliable.
But it seems that it goes a bit against your explanations. Or is it just the way std::result_of<>
is broken in this case?
#include <type_traits>
class base
{
protected:
double operator()(){ return 1; };
int operator()(int i){ return i; };
};
class child : private base
{
public:
auto operator()()
-> decltype(base::operator()())
{
return base::operator()();
}
auto operator()(int i)
-> decltype(base::operator()(std::declval<int>()))
{
return base::operator()(i);
}
};
Thanks for your time.
If your code is literally this, then you can exploit the fact that the protected operator()
from base
is also available in child
, and use a simple trait:
template <typename> struct memfn_result;
template <typename C, typename R, typename ...Args>
struct memfn_result<R (C::*)(Args...)>
{
using type = R;
};
class base
{
protected:
int operator()(){ return 1; };
};
class child : private base
{
memfn_result<decltype(&child::operator())>::type a; // "a" is an "int"
};
Since base::operator()()
is protected
and you are using it on an object of type base
rather than an object of type child
you clearly can't access the member! You need to access the function call operator using an object of type child
. Sadly, child
is incomplete in the context where you are trying to access it, i.e., you need to an indirection:
class child
: private base {
auto static doSomeMethod()
-> decltype((std::declval<base>().*(&child::operator()))()) {
return 1;
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With