Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is decltype of a non-static member function ill-formed?

I'm not sure to perfectly understand [dcl.type]/4.3:

For an expression e, the type denoted by decltype(e) is defined as follows:

  • [...]
  • (4.3) otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access, decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;
  • [...]

For me, the emphasized part both apply to id-expression and class member access, right?

Playing with my favorite compiler, I get the following.

✓ Accepted by the compiler

namespace N { void f() {} }
using type = decltype(N::f);
type* pf = N::f;

Ok I guess; N::f is an unparenthesized id-expression and does not name a set of overloaded functions.

✗ Rejected by the compiler

namespace N { void f() {} void f(int) {} }
using type = decltype(N::f); // error: decltype cannot resolve address of overloaded function
type* pf = N::f;

Ok; N::f does name a set of overloaded functions.

✗ Rejected by the compiler

struct S { void f(){} };
using type = decltype(S::f); // error: invalid use of non-static member function 'void S::f()'
type* pf = &S::f;

Hum? S::f would name a set of one overloaded function?


All in all, is my understanding of [dcl.type]/4.3 just bad? is gcc trunk wrong? both? none? kamoulox?

like image 918
YSC Avatar asked Sep 26 '18 14:09

YSC


People also ask

Is Decltype runtime or compile time?

decltype is a compile time evaluation (like sizeof ), and so can only use the static type.

What is a non static member function?

A non-static member function is a function that is declared in a member specification of a class without a static or friend specifier. ( see static member functions and friend declaration for the effect of those keywords)

What happens if non static members are used in static member function?

What happens if non static members are used in static member function? Explanation: There must be specific memory space allocated for the data members before the static member functions uses them. But the space is not reserved if object is not declared.

Can static member functions access non static data members?

Static member function: it can only access static member data, or other static member functions while non-static member functions can access all data members of the class: static and non-static.


1 Answers

The simple reason is that the use of S::f is constrained for class members.

[expr.prim.id]

2 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 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 ([expr.unary.op]), or
  • if that id-expression denotes a non-static data member and it appears in an unevaluated operand.

The last bullet, the one related to your code, only applies to non-static data member. There is no provision for functions.

I can only speculate as to why it's not allowed, though I previously asked that question.

like image 61
StoryTeller - Unslander Monica Avatar answered Sep 17 '22 17:09

StoryTeller - Unslander Monica