I have seen the following topic: Resolve const and non-const member function pointer
But I wonder if there's a generic-programming friendly way of doing it as of C++11 or newer. For the sake of example, imagine the following class:
struct S
{
int v = 42;
int& value() { return v;}
int value() const {return v;}
};
the following helper class
template<typename T>
struct Holder
{
using TYPE = T;
};
However when I try this:
auto l = [](auto holder)
-> decltype(&(std::add_const_t<typename decltype(holder)::TYPE>::value))
{
return &(std::add_const_t<typename decltype(holder)::TYPE>::value);
};
I keep getting the following error from GCC:
error: 'decltype' cannot resolve address of overloaded function
while clang just crashes during compilation.
Why is that, if:
static_assert(
std::is_same_v<
const S,
std::add_const_t<Holder<std::decay_t<S>>::TYPE>>,
"");
https://godbolt.org/z/e5E7Ts156
Should that be the case, or have I bumped into a weird defect/corner case?
You can do something like this:
template <typename Owner, typename Ret, typename... Arg>
constexpr auto getConstFuncPtr(Ret (Owner::*mfpc)(Arg...) const) { return mfpc; }
template <typename Owner, typename Ret, typename... Arg>
constexpr auto getNonConstFuncPtr(Ret (Owner::*mfpnc)(Arg...)) { return mfpnc; }
auto mfpc = getConstFuncPtr(&S::value);
auto mfpnc = getNonConstFuncPtr(&S::value);
There is an implicit conversion (which is not a cast) that helps decide which function to take.