函数签名指针与指针引用=没有区别

std::function signature pointer vs pointer reference = no difference?

本文关键字:指针 有区别 引用 函数      更新时间:2023-10-16

代码示例:

 #include <string>
 #include <functional>
 struct Foo {};
 typedef bool func_type(Foo *&, const std::string&);
 typedef std::function<bool(Foo*&, const std::string&)> FunctionalType;
 bool f(Foo *, const std::string&)
 {
 }
 int main()
 {
 #if 1
   func_type *func;
   func = f;
 #else
   FunctionalType f2;
   f2 = f;
#endif
}

正如你所看到的,我已经声明了函数类型,"引用指针"作为第一个参数Foo *&,我希望函数只有"指针"作为第一个参数Foo *不能被分配给这种类型的变量。

#if 1区域编译失败(如我所料);但是,替代方法没有产生任何错误:

FunctionalType f2;
f2 = f;
  1. 为什么它编译没有错误(至少gcc 5.2和clang 3.7)?

  2. 如何修复,使std::function<Params>不接受f转换?

std::function<R(Ts...)>定义为一种类型,其对象可以表示任何可以带参数Ts...调用且返回值可转换为R的函数。

由于您的函数f可以使用类型为T*的左值作为第一个参数来调用(这是您的Foo *&强加的要求),因此它是存储在std::function中的有效函数。

据我所知,没有办法抑制这个行为

std::function是可调用对象的类型擦除容器。

它将存储任何c++类型的实例,这些实例可以被复制、销毁,并且可以用"兼容"签名调用。

本例中签名为bool(Foo*&, const std::string&)

核心思想是,当std::function类型的R(Args...)部分中的Args...Foo*&, const std::string&时,这些参数可以传递给期望Foo*const std::string&的函数。

std::function基于兼容性工作,而不是精确匹配签名。

如果你真的,真的需要禁止不接受引用的东西:

template<class T>
struct reference_only {
  T& t;
  operator T&(){ return t; }
  operator T()=delete;
  reference_only(T& tin):t(tin){}
};

然后使用:

typedef std::function<void(reference_only<Foo*>)> FunctionalType;

不喜欢被转换为值类型,但接受被转换为引用类型(在本例中为Foo*&类型)。

实例编译,实例不编译