16
class A {
    int f(int x, int j) { return 2;}
    decltype(f)* p;
};

Gives me the error:

error: decltype cannot resolve address of overloaded function

I can't understand why that error is even speaking of overloaded functions. Similarly I thought that maybe I needed to use the scope operator to access the function:

class A {
    int f(int x, int j) { return 2;}
    decltype(A::f)* p;
};

Which still gives me an error but a clearer description:

error: invalid use of non-static member function 'int A::f(int, int)'

Why is it that I'm not allowed to use decltype to find the type of a member function? Alternatively setting the member function to static removes the error in either case.

Silversonic
  • 1,289
  • 2
  • 11
  • 26

1 Answers1

13

What you really want is:

struct a {
    int f(int x, int j) { return 2;}
    decltype(&a::f) p;
};

Live demo

Since the f you are referring to is a member function. The deduced type is:

int(a::*)(int, int)

Without the & the compiler is assuming that you are trying to call the function without providing arguments to it. Perhaps Clang's error message is clearer about this:

error: call to non-static member function without an object argument
    decltype(a::f) p;

If you really don't want the pointer type you can later apply std::remove_pointer_t from <type_traits>.

Shoe
  • 74,840
  • 36
  • 166
  • 272
  • "the compiler is assuming that you are trying to call the function without providing arguments to it." That's weird since it would not assume that if I passed decltype with the name of an ordinary function. Also I was not aware that the type of class members is preceded by a scope operator - what should I look up to understand that a bit better? – Silversonic Oct 13 '15 at 23:03
  • @Silversonic "Member function pointer" I guess. Remember that any non static member function needs to also have `this` "implicitly passed to it" so you can see a `Return(Class::*)(Arg1, Arg2, ...)` as `Return(Class* const, Arg1, Arg2, ...)` and that's why `Return(Class::*)(Arg1, Arg2, ...)` and `Return(*)(Arg1, Arg2, ...)` cannot possibly be the same type. – Shoe Oct 13 '15 at 23:10