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:
g++ -Wall -Wextra -pedantic -std=c++14
clang++ -Wall -Wextra -pedantic -std=c++14
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
inconsistencystruct methods
{
/* ... */
function_type mem_fun_deleted = delete;
};
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
inconsistencystruct methods
{
/* ... */
using assignment_type = methods& (methods const&);
assignment_type operator= = default;
};
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
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
Which compilers are right here?
Furthermore, is it possible to:
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.
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.
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.
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);
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.
§ 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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With