Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring member function using function type syntax

Tags:

c++

g++

clang++

cl

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.

like image 691
Adam Badura Avatar asked Jul 13 '17 08:07

Adam Badura


People also ask

What is the syntax for declaring a function?

Declaring a function - function prototypestype functionName( type [argname] [, type, ...] ); Example: // declare a function prototype for the add function, taking two integer // arguments and returning their sum int add (int lhs, int rhs); In C and C++, functions must be declared before the are used.

What is member function in C++ syntax?

Member functions are operators and functions that are declared as members of a class. Member functions do not include operators and functions declared with the friend specifier. These are called friends of a class. You can declare a member function as static ; this is called a static member function.

What is the correct syntax for calling a member function?

The syntax looks like you are preceding the dereferenced pointer with an object member selection (the “dot” operator) or object pointer selection (the “arrow” operator). Calling the member function on an object using a pointer-to-member-function result = (object. *pointer_name)(arguments);

What is member function in C++ with example?

A member function of a class is a function that has its definition or its prototype within the class definition like any other variable. It operates on any object of the class of which it is a member, and has access to all the members of a class for that object.


1 Answers

§ 8.3.5 Functions [dcl.fct] p12 A typedef of function type may be used to declare a function but shall not be used to define a function.

Thus Clang is right to reject the code in all cases and compilers that accept it are in the wrong.

(The quotation is from N4618 but the rule is a part of the language since forever).

like image 71
n. 1.8e9-where's-my-share m. Avatar answered Sep 30 '22 15:09

n. 1.8e9-where's-my-share m.