C++ - 为什么std :: function <some_type_t,void>无效?

ai2*_*221 4 c++ templates void c++17

在C++中,如果我尝试这样做:

std::function<void(bool,void)>
Run Code Online (Sandbox Code Playgroud)

那么编译器会抛出错误.为什么是这样?在许多情况下它很有用.一个例子:

//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;
}
Run Code Online (Sandbox Code Playgroud)

如果用户希望在其回调中可选地具有附加数据,则这允许非常干净的语法,但不是必须的.但是,编译器将拒绝尝试初始化对象的代码callback_with_just_bool

为什么会这样,是否有一个干净的方式?谢谢.

编辑:在现实世界的代码中,我尝试这样做的具体原因是在事件系统中.有提供给事件系统有关希望单个对象的数据有条件接收事件(例如,"如果你足够接近源,您会收到一个声音事件")所提供的数据,以及一个回调有关的事件(例如"X200 Y200的10khz噪音").大多数情况下,检查需求所需的数据将存在于提供给有关事件的回调的数据中,但我想提供一个可选的附加数据结构(如果不是这种情况).因此,如果用户不需要这种额外的数据结构,则用户将指定"void".

Edg*_*jān 9

"为什么是这样?"

因为void参数列表中唯一允许的用法是显示该函数不接受任何参数.

[功能]:

void

表示该函数不带参数,它是空参数列表的确切同义词:int f(void);int f();声明相同的函数.请注意,类型void(可能是cv-qualified)不能在参数列表中使用,否则:int f(void, int);并且int f(const void);是错误(尽管派生类型,例如void*可以使用)

"周围有干净的方式吗?"

我建议专攻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;
};
Run Code Online (Sandbox Code Playgroud)