2015-10-14 54 views
4

下面是代码示例:std ::函数签名指针vs指针引用=没有区别?

#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和3.7哗​​)?

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

回答

3

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

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

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

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

Live example compilinglive example not compiling

4

std::function<R(Ts...)>被定义为类型,其目的可以代表了可以用参数Ts...并且其返回值为可转化为R被调用的任何功能。

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

没有办法抑制我所知道的这种行为。

+0

我将另一个答案标记为答案,因为它为(2)提供了一些解决方法。 – fghj