Hind Forsum
Hind Forsum

Reputation: 10507

C++11 applies result_of on member function, failed, why?

I've got the following code as an experiment:

int f1() { return 0; }

struct Bar {
    Bar() = delete;
    int f() { return 0; }
    int operator()() { return 1; }
};

int main()
{
    decltype(f1()) x = 3;//f1() is expression
    result_of<decltype(&f1)()>::type x1 = 3;//type+param
    result_of<Bar()>::type x3 = 3;//type+param
    decltype(declval<Bar>().f()) y = 4;//expression
    decltype((((Bar*)nullptr)->*(&Bar::f))()) z = 5;//expression

    result_of<decltype(std::mem_fn(&Bar::f))()>::type y2 = 3;//error!!!!!!
}

Everything is OK except the last result_of: I was trying to get the return type of Bar::f, using result_of.

Why it failed, and how to correct it?

Upvotes: 1

Views: 241

Answers (1)

Piotr Skotnicki
Piotr Skotnicki

Reputation: 48457

The unspecified return type of mem_fn:

template <class R, class T>
unspecified mem_fn(R T::* pm) noexcept;

is defined in terms of INVOKE [func.memfn]/p1:

1 Returns: A simple call wrapper ([func.def]) fn such that the expression fn(t, a2, ..., aN) is equivalent to INVOKE(pm, t, a2, ..., aN) ([func.require]).

where the definition of INVOKE includes the following two bullets [func.require]/p1:

Define INVOKE(f, t1, t2, ..., tN) as follows:

(t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and is_base_of<T, decay_t<decltype(t1)>>::value is true;

((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 does not satisfy the previous two items;

That is, the first argument of what mem_fn returns must be the type of the implicit object parameter (t1), either a reference or a pointer, e.g.:

std::result_of<decltype(std::mem_fn(&Bar::f))(Bar&)>::type y2;
//                                            ~~~^

std::result_of<decltype(std::mem_fn(&Bar::f))(Bar*)>::type y2;
//                                            ~~~^

You could also remove std::mem_fn altogether:

std::result_of<decltype(&Bar::f)(Bar*)>::type y2;

Upvotes: 2

Related Questions