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".
"为什么是这样?"
因为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)