无效的?,c++,templates,c++17,void"/>

首页 > 解决方案 > C++ - 为什么是 std::function无效的?

问题描述

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

std::function<void(bool,void)>

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

//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;
}

如果用户希望在他们的回调中选择性地包含其他数据,但不是必须的,这允许使用非常简洁的语法。但是,编译器将拒绝尝试初始化对象的代码callback_with_just_bool

为什么会这样,是否有干净的解决方法?谢谢。

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

标签: c++templatesc++17void

解决方案


“为什么是这样?”

因为void在参数列表中唯一允许的用法是表明该函数不接受任何参数。

[功能]

void

表示该函数不带参数,它是空参数列表的确切同义词:int f(void);int f();声明相同的函数。请注意,类型 void(可能是 cv 限定的)不能在参数列表中使用: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;
};

推荐阅读