Declaring member function using function type syntax

Viewed 765

Just recently I learned that you can declare a function (including methods) using variable-like syntax with function type:

using function_type = int (double);
// pre-C++11:
//typedef int function_type(double);

function_type fun_global;

struct methods
{
    static function_type mem_fun_static;
    function_type mem_fun_normal;
    virtual function_type mem_fun_virtual;
    virtual function_type mem_fun_abstract = 0;
};

In above code

  • fun_global is a global function,
  • mem_fun_static is a static member function,
  • mem_fun_normal is an ordinary method,
  • mem_fun_virtual is a virtual method,
  • mem_fun_abstract is an abstract method.

All of them take single argument of type double and return int value - just like the function_type says.

All this years I know C++ and I didn't know about this - this language never stops surprising me! By the way - is this syntax mentioned anywhere here? I don't see this...

However, while exploring this new to me feature I stumbled upon some inconsistencies between compilers. For tests, I was using following compilers:

  • GCC 5.4.0 and 7.1.0, command line: g++ -Wall -Wextra -pedantic -std=c++14
  • Clang 4.0.1, command line: clang++ -Wall -Wextra -pedantic -std=c++14
  • MSVC 19.10.25019 (VS 2017), command line: cl /W4 /EHsc

In tests that I run both GCC versions gave same result so further I'm referring to them just as GCC.


= delete inconsistency

struct methods
{
    /* ... */
    function_type mem_fun_deleted = delete;
};
  • GCC: OK
  • Clang: error!

    Test.cpp:13:34: error: '= delete' is a function definition and must occur in a standalone declaration
            function_type mem_fun_deleted = delete;
                                            ^
    1 error generated.
    
  • MSVC: OK

= default inconsistency

struct methods
{
    /* ... */
    using assignment_type = methods& (methods const&);
    assignment_type operator= = default;
};
  • GCC: OK
  • Clang: error!

    Test.cpp:14:30: error: '= default' is a function definition and must occur in a standalone declaration
            assignment_type operator= = default;
                                        ^
    1 error generated.
    
  • MSVC: error!

    Test.cpp(14): error C2206: 'methods::operator =': typedef cannot be used for function definition
    

Inline definition inconsistency

struct methods
{
    /* ... */
    function_type mem_fun_inline { return 0; }
};
  • GCC: error!

    Test.cpp:13:43: error: invalid initializer for member function ‘int methods::mem_fun_inline(double)’
      function_type mem_fun_inline { return 0; }
                                               ^
    Test.cpp:13:43: error: expected ‘;’ at end of member declaration
    
  • Clang: error!

    Test.cpp:13:33: error: expected expression
            function_type mem_fun_inline { return 0; }
                                           ^
    Test.cpp:7:8: error: missing '}' at end of definition of 'methods'
    struct methods
           ^
    /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/x86_64-pc-cygwin/bits/c++config.h:194:1: note: still within definition of 'methods' here
    namespace std
    ^
    2 errors generated.
    
  • MSVC: OK


Questions

Which compilers are right here?

Furthermore, is it possible to:

  1. In the inline definition (supported only by MSVC) refer somehow to the argument?
  2. Somehow use the function_type also at definition of those functions (when done outside of the class). Following is OK (with all compilers)

    struct methods
    {
        static function_type mem_fun_static;
        /* ... */
    };
    
    int methods::mem_fun_static(double) { return 0; }
    

    It is not that bad since change of function_type should result in compilation error at function definition (as it will no longer match declaration) - but still maybe it is possible to avoid even that.

1 Answers
Related