Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type of the first parameter of a member function in C++11

I have written a metafunction to retrieve the type of the first parameter of a member function, which of course receives one or more parameters. The code I have written is as follow:

template <typename...> struct parameter;

template < typename O, typename A, typename R, typename... Args>
struct parameter <R (O::*)(A, Args...)  > {
     using first_param = A;
};

I use this meta function as follow:

using mem_fn = void(mem_type::*)(std::vector<int>);
using f_pm = parameter<mem_fn>::first_param;

and it compiles and works. But when I have a class:

struct mem_type{

    void update(std::vector<int>) {

    }
};

and use my metafunction as follow:

using mem_fn = decltype(mem_type::update);
using f_pm = parameter<mem_fn>::first_param;

the code does not compiles and visual studio 2013 gives: error C2027: use of undefined type parameter<mem_fn>.

Does anyone knows the reason for this error?

like image 551
Raul Alonso Avatar asked Nov 26 '14 21:11

Raul Alonso


1 Answers

First, an id-expression naming a nonstatic member function (mem_type::update in this case) can't be used as an unevaluated operand (such as the operand of decltype). §5.1.1 [expr.prim.general]/p13 (footnote omitted):

An id-expression that denotes a non-static data member or non-static member function of a class can only be used:

  • as part of a class member access (5.2.5) in which the object expression refers to the member’s class or a class derived from that class, or
  • to form a pointer to member (5.3.1), or
  • if that id-expression denotes a non-static data member and it appears in an unevaluated operand.

§7.1.6.2 [dcl.type.simple]/p4:

The operand of the decltype specifier is an unevaluated operand (Clause 5).

And even if update were a regular function, decltype would produce a function type rather than a function pointer type, and your specialization matches a pointer-to-member-function type.

You need to created a pointer-to-member-function with & - i.e., decltype(&mem_type::update).

like image 111
T.C. Avatar answered Oct 14 '22 15:10

T.C.