C++ – Why is std::function<some_type_t, void> invalid?

  • A+

In C++, if I try to do this:


then the compiler will throw errors. Why is this? It's useful in many cases. One example:

//g++ -std=c++17 prblm.cpp #include <cstdio> #include <functional>  template<class type_t> class some_callback {     public:         using callback_t = std::function<void(bool,type_t)>;         some_callback(callback_t _myfunc)         {             this->myfunc = _myfunc;         }         callback_t myfunc; };  using callback_with_just_bool = some_callback<void>; using callback_with_an_int_too = some_callback<int>;  int main() {     auto my_callback_with_int = callback_with_an_int_too([](bool x, int y)     {     }); //OK      auto my_callback_just_bool = callback_with_just_bool([](bool x)     {     }); //Error      auto my_callback_just_bool = callback_with_just_bool([](bool x,void z)     {     }); //Error     return 0; } 

This allows for a very clean syntax if the user would like to optionally have additional data in their callback, but not have to. However, the compiler will reject code that tries to initialize an object of callback_with_just_bool

Why is it like this, and is there a clean way around it? Thanks.

Edit: The specific reason I'm trying to do this, in real world code, is in an event system. There is data provided to the event system about an individual object that wishes to conditionally receive events (e.x. "if you're close enough to the source, you'll receive a sound event") as well as data provided to a callback about the event (e.x. "a 10khz noise at X200 Y200"). Most of the time, the data needed to check the requirements will exist inside the data provided to the callback about the event, but I wanted to provided an optional additional data structure if that was not the case. Hence, the user would specify "void" if they didn't need this additional data structure.


"Why is this?"

Because the only permitted usage of void in a parameter list is to show that the function doesn't accept any parameters.

From [function]:


Indicates that the function takes no parameters, it is the exact synonym for an empty parameter list: int f(void); and int f(); declare the same function. Note that the type void (possibly cv-qualified) cannot be used in a parameter list otherwise: int f(void, int); and int f(const void); are errors (although derived types, such as void* can be used)

"Is there a clean way around it?"

I would suggest to specialize for void:

template<class type_t> class some_callback {     std::function<void(bool,type_t)> myfunc; };  template<> class some_callback<void> {     std::function<void(bool)> myfunc; }; 


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: