2015-10-14 96 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