c++ - How to write a constant function reference -
at moment have class defined similar this:
class dummy{ public: dummy(void(&func)(int)) : member{func}{} void(&member)(int); };
but want have member
defined const
function reference. i'm not sure how write or if possible.
p.s. please don't recommend me std::function
i'm not oblivious it's existence , have no objection it, want know whether doable.
the syntax:
syntactically, can achieve through type alias (or typedef
):
using function_t = void(int); // or typedef void (function_t)(int); class dummy { public: const function_t& member; dummy(const function_t& func) : member{func}{} };
the semantics:
however, "correct syntax" doesn't buy anything: dummy
same as
class dummy { public: function_t& member; dummy(function_t& func) : member{func}{} };
(which, in turn same op's definition) because const
qualifiers ignored per c++11 8.3.5/6:
the effect of cv-qualifier-seq in function declarator not same adding cv-qualification on top of function type. in latter case, cv-qualifiers ignored. [ note: function type has cv-qualifier-seq not cv-qualified type; there no cv-qualified function types. —end note ]
what rvalues?
as far undestand (from comment user657267's answer) motivation taking argument reference const
enable passing rvalues (temporaries):
void f(int) { } function_t make_function() { return f; } dummy d1(f); dummy d2(make_function());
however, doesn't compile, not because of dummy
, because make_function
returns function forbiden c++11 8.3.5/8
if type of parameter includes type of form “pointer array of unknown bound of
t
” or “reference array of unknown bound oft
,” program ill-formed.99 functions shall not have return type of type array or function, although may have return type of type pointer or reference such things. there shall no arrays of functions, although there can arrays of pointers functions.
a natural "solution" returning reference:
function& make_function() { return f; }
or
function&& make_function() { return f; }
in both cases, type of expression make_function()
lvalue (which defies purpose of dummy
using reference const
enable passing rvalues) per c++11 5.2.2/10
a function call lvalue if result type lvalue reference type or rvalue reference function type, xvalue if result type rvalue reference object type, , prvalue otherwise.
actually, value category not issue here. legal declaration of make_function
, definition of dummy
seem above declarations of d1
, d2
work fine.
nevertheless, mentioned comment user657267's answer talks passing lambda reference function cannot bind lambda expression because has different type:
dummy d3([](int){}); // error!
the suggested solution
instead of references use pointers:
using function_t = void(int); // or typedef void (function_t)(int); class dummy { public: function_t* member; dummy(function_t* func) : member{func}{} }; void f(int) { } function_t& make_function() { return f; } dummy d1(f); // ok dummy d2(make_function()); // ok dummy d3([](int){}); // ok
final remarks:
again, declaring
const function_t* member
,dummy(const function_t* func)
doesn't buy because, per references,const
qualifiers ignored.the initialization of
d1
,d2
work because functions implicitly converted pointer functions (see c++ 4.3/1).if function argument of function type, compiler changes type pointer function. hence,
dummy
's constructor can declareddummy(function_t func);
.the initialization of
d3
works because captureless lambdas implicitly converted pointer functions. wouldn't work lambdas captures.
Comments
Post a Comment