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 of t,” 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:

  1. again, declaring const function_t* member , dummy(const function_t* func) doesn't buy because, per references, const qualifiers ignored.

  2. the initialization of d1 , d2 work because functions implicitly converted pointer functions (see c++ 4.3/1).

  3. if function argument of function type, compiler changes type pointer function. hence, dummy's constructor can declared dummy(function_t func);.

  4. the initialization of d3 works because captureless lambdas implicitly converted pointer functions. wouldn't work lambdas captures.


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -