1. Revision History
1.1. Revision 0 - November 21st, 2014
Initial release.
2. Motivation
One frequent question from beginner and intermediate users of C++ is what 
The problem grows greater in generic code, where both library developers and standard library vendors often take "callables". Sometimes it works, in the case of 
struct my_object { int value = 0 ; bool is_zero () const { return value == 0 ; } // ... }; // ... std :: vector < my_object *> objects ; // uhhh....? auto it = std :: find_if ( objects . begin (), objects . end (), & my_object :: is_zero ); 
Individuals want to pass pointer to member functions and pointers to member objects, requiring quite a bit of boilerplate with either a lambda, 
... it would point directly to the failing call instead of failing inside the code of a mem_fn equivalent, which would be really convenient. It’s worth noting that I had to fix functions several times in my library to add the missing call to as_function, which would have never been a problem with an intuitive call syntax. -- Morwenn, author of [cpp-sort]
With the introduction of 
While we have been saved from having 31 separate implementations of 
Therefore, we propose to obviate 
3. Design
This design pulls from two previous papers. Peter Dimov’s September 2004 N1695 - A Proposal to make Pointers to Members Callable and Barry Revzin’s June 2017 p0312 - Making Pointers to Members Callable. It makes both pointer to member functions and pointer to member objects callable.
The goal of the design for this proposal is to make the simple and non-unique syntax have intrinsic and worthwhile value for both the novice and the expert programmer.
3.1. But what about UFCS-
No. This is not Universal Functional Call Syntax (UFCS), has nothing to do with UFCS, and never will be UFCS. There is no correlation between fully-typed objects that are of type Pointer to Member Object or Pointer to Member Function having a specific invocation syntax and the leviathan that is Name Lookup, the resulting Argument-Dependent Lookup (ADL) and all it implies. Pointer to member objects and pointer to member functions are fully resolved entities that do not deal with overload resolution or name lookup.
This proposal and other UFCS proposal are not in any way correlated. If anyone claims as such or attempts to use this paper as support for UFCS should be promptly directed to this section of the paper.
3.2. Callable Members
In line with the goals of this proposal, we propose a very simple syntax that will allow generic code to treat all classes of "callables" -- as conceived by the 
- 
     Function pointers, objects with operator () 
 f_ptr ( arg1 , arg2 , ..., argN ); 
 f_obj ( arg1 , arg2 , ..., argN ); 
- 
     Pointer to member function pmf 
 ( obj . * pmf )( arg1 , arg2 , ..., argN ); pmf ( obj , arg1 , arg2 , ..., argN ); 
- 
     Pointer to member object pmo 
 auto value = ( obj . * pmo ); auto value = pmo ( obj ); 
 ( obj . * pmo ) = new_value ; pmo ( obj , new_value ); 
N.B.: this syntax treats the arguments passed to pointer to members like any other argument, meaning that types which have conversions to 
3.3. References, Pointers, and std::reference_wrapper, oh my!
The additional question is whether or not pointer to member functions and pointer to member objects should work with 
For 
3.4. Improvement of usage with the Standard Library
The code presented in §2 Motivation now compiles without problem:
std :: vector < my_object *> objects ; // yay! auto it = std :: find_if ( objects . begin (), objects . end (), & my_object :: is_zero ); 
This is an immense boon to both clarity and usability. People who perform this operation expecting a "callable" to work in this scenario have it simply work, and age-old search engine entries for "how to use member function with C++ algorithm" will dramatically decrease as code that people expect to work and have no other valid interpretation actually does exactly that!
We think lambdas have been an immense boon, but do not cover the terse and simple situations. Lambdas are great general tools to solve this problem, but feel that this paper occupies an important use case in the use of C++. Most intermediate developers who grasp the Standard Library have tried to write the code seen above with one algorithm or another: rewarding programmer intuition is a powerful way to reinforce confidence in both the language and their own skill. C++ is in a unique position in that there are many places where the language has room to reward programmer intuition: this is one such place.
4. Impact
This proposal is an extension to the Core language. Its potential impacts are as follows.
4.1. On the Standard
If an implementation of 
There are no backwards compatibility compromises or breaks for this feature in the standard. The usage of parenthesis and function call syntax in this case do not conflict or produce grammar or parsing ambiguities or errors.
4.2. On User Code
The proposal enables syntax that was not previously enabled. This may only break code which relied on the fact that certain non-evaluated context SFINAE’s that implemented their own version of 
The good news is that the fix is easy: delete the offending overloads since only 1 is valid. In many cases, deleting the function altogether would be a plausible fix and just invoking the callable directly!
There are also no known cases where the intent of the code changes or the behavior changes into a form that will silently break code, and all breakages due to the above are loud and easily-fixable compile-time errors.
5. Proposed Wording and Feature Test Macros
The following wording is relative to [n4762].
5.1. Proposed feature Test Macro
The recommended feature test macro is 
5.2. Intent
The intent of this wording is to add 
5.3. Proposed Wording
Modify §7.6.1.2/1 [expr.call]/1 to read as follows:
1 A function call is a postfix expression followed by parentheses containing a possibly empty, comma-separated list of initializer-clauses which constitute the arguments to the function. The postfix expression shall havefunction type or function pointer typefunction type, function pointer type, or pointer-to-member type . For a call to a non-member function or to a static member function, the postfix expression shall be either an lvalue that refers to a function (in which case the function-to-pointer standard conversion (7.3.3) is suppressed on the postfix expression), or it shall have function pointer type.
Add one clause after §7.6.1.2/2 [expr.call]/2:
3 For a call of the form, wherepm ( a1 , ..., aN ) is of type "pointer to member ofpm ".T 
- — if
is a pointer to member function takingpm arguments, thenM shall beN . The result of the expression shall be equivalent to calling a pointer to member function (7.6.4) with the syntax1 + M if( a1 . * pm )( a2 , ..., aN ) is a possibly cv-qualified class type of whicha1 is a base class. Otherwise, the behavior of the expression shall be equivalent toT .( a1 ->* pm )( a2 , ..., aN ) - — if
is a pointer to data member, then eitherpm 
- —
shall beN . The behavior of the function call shall be as-if invoking a pointer to member data (7.6.4) with1 ifa1 . * pm is a possibly cv-qualified class type of whicha1 is a base class or is convertible to such a class type,T otherwise. Or,a1 ->* pm - —
shall beN . The behavior of the function call shall be as-if assigning the second argument2 to the result of a pointer to member data (7.6.4) witha2 if( a1 . * pm ) = a2 is a possibly cv-qualified class type of whicha1 is a base class or is convertible to such a class type,T otherwise.( a1 ->* pm ) = a2 
Append to §14.8.1 Predefined macro names [cpp.predefined]'s Table 16 with one additional entry:
Macro name Value __cpp_invokable_members 201811L 
6. Acknowledgements
Thank you to Jason Turner for showing me some of the internals of ChaiScript a long time ago and bringing this common problem to light. Thank you to Stephan T. Lavavej for talking about this during one of his talks. Thank you to Barry Revzin and Peter Dimov for their previous work and scholarship on this matter.