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 astatic
member function,mem_fun_normal
is an ordinary method,mem_fun_virtual
is avirtual
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:
- In the inline definition (supported only by MSVC) refer somehow to the argument?
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.
std::function
. Again, more self documenting code. – Simply