C++ 我的slot类错过了std::函数的哪些功能?

C++ 我的slot类错过了std::函数的哪些功能?,c++,c++11,functional-programming,std-function,C++,C++11,Functional Programming,Std Function,我编写了自己的“slot”又名“callable wrapper”,因为我想在其他对象上提供成员函数slot重新绑定(即,我需要一种方法来存储成员函数指针和指向相关类的指针) 我运行了一个小规模测试,发现我的系统(64位Linux)上的std::function是我自己实现的类似类的两倍(GCC/libstdc++)到三倍(Clang/libc++),大小为16字节。非成员函数和lambda的实现如下所示(第一个参数是为了与此处未显示的成员函数插槽保持一致): 模板 班槽 { 公众: virtu

我编写了自己的“slot”又名“callable wrapper”,因为我想在其他对象上提供成员函数slot重新绑定(即,我需要一种方法来存储成员函数指针和指向相关类的指针)

我运行了一个小规模测试,发现我的系统(64位Linux)上的
std::function
是我自己实现的类似类的两倍(GCC/libstdc++)到三倍(Clang/libc++),大小为16字节。非成员函数和lambda的实现如下所示(第一个参数是为了与此处未显示的成员函数插槽保持一致):

模板
班槽
{
公众:
virtual~slot()=默认值;
虚拟void操作符()(const void*对象,ArgTypes…)const=0;
受保护的:
slot()=默认值;
};
模板
类可调用\u插槽:公共插槽
{
公众:
可调用的\u插槽(可调用函数\u指针\u或\u lambda):可调用(函数\u指针\u或\u lambda){}
虚拟void运算符()(常量void*,ArgTypes…args)常量重写{callable(args…;}
私人:
可调用的可调用的;
};
模板
类可调用\u插槽:公共插槽
{
公众:
可调用的\u插槽(可调用函数\u指针\u或\u lambda):可调用(函数\u指针\u或\u lambda){}
虚拟void运算符()(const void*)const override{callable();}
私人:
可调用的可调用的;
};
模板
使用函数\u slot=可调用\u slot;
我知道这里没有实现像
target
这样的功能,但我认为任何缺少的函数都不会增加对象的大小


我想问的是:为什么
std::function
的大小比我上面的廉价实现要大?

您的类功能与
std::function
提供的类功能非常不同。您请求类的用户提供“可调用”对象的实际类型作为模板的参数

相反,
std::function
不需要此功能,并且可以处理任何可调用对象,只要它具有所需接口的
operator()
。尝试将模板用于未知类型的对象,例如,
std::bind
的结果,您就会明白我的意思


由于功能非常不同,大小的比较是没有意义的。

您的
函数\u slot
接受一个
可调用的
和一组
参数…
,并返回一个继承自
slot
的类型和一个
虚拟操作符()

要以多态方式将其用作值,必须将其包装在智能指针中并存储在堆上,并且必须将包装类
operator()
转发到
slot
one

std::function
对应于该包装器,而不是您的
slot
callable\u slot
对象

template<class...Args>
struct smart_slot {
  template<class Callable> // add SFINAE tests here TODO! IMPORTANT!
  smart_slot( Callable other ):
    my_slot( std::make_unique<callable_slot<Callable, Args...>>( std::move(other) ) )
  {}
  void operator()( Args...args ) const {
    return (*my_slot)(std::forward<Args>(args)...);
  }
  // etc
private:
  std::unique_ptr<slot<Args...>> my_slot;
};
它不会对
std::function
的适当实现进行动态分配


请注意,一些主要的库供应商在这种情况下会进行动态分配。

std::function
有一个小对象优化。类型擦除可以由make\u slot helper函数处理,不是吗?
template<class...Args>
struct smart_slot {
  template<class Callable> // add SFINAE tests here TODO! IMPORTANT!
  smart_slot( Callable other ):
    my_slot( std::make_unique<callable_slot<Callable, Args...>>( std::move(other) ) )
  {}
  void operator()( Args...args ) const {
    return (*my_slot)(std::forward<Args>(args)...);
  }
  // etc
private:
  std::unique_ptr<slot<Args...>> my_slot;
};
std::function<void(std::ostream&)> hello_world =
  [s = "hello world"s](std::ostream& os)
  {
    os << s;
  };
hello_world(std::cout);