std :: function signature pointer vs pointer reference =没有区别?

时间:2015-10-14 12:58:08

标签: c++ function pointers c++11

以下是代码示例:

 #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
}

如您所见,我已声明函数类型为&#34;引用指针&#34;作为第一个参数Foo *&,我希望该函数只有&#34;指针&#34;因为第一个参数Foo *不能分配给这种类型的变量。

#if 1区域无法编译(正如我所料);但是,替代方案没有发出任何错误:

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

  2. 如何修复它,以便std::function<Params>不接受f进行转换?

2 个答案:

答案 0 :(得分:4)

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

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

无法抑制我所知道的这种行为。

答案 1 :(得分:3)

std::function是一个可以调用的东西的类型擦除容器。

它将存储任何C ++类型的实例,可以使用“兼容”签名复制,销毁和调用。

在这种情况下,签名为bool(Foo*&, const std::string&)

核心思想是,当Args...类型的R(Args...)部分std::functionFoo*&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*&)。

Live example compilinglive example not compiling