2015-07-01 31 views
3

我有兩個函數foo的重載,它們取不同的std::function s,當與std::bind的結果一起使用時,會導致後者的模糊問題。我不明白爲什麼只有這是不明確的。與std :: function參數不同的重載與bind(有時)是不明確的

void foo(std::function<void(int)>) {} 
void foo(std::function<int()>) {} 

void take_int(int) { } 
int ret_int() { return 0; } 

當使用int()具有bind函數I得到一個歧義錯誤

foo(std::bind(ret_int)); // ERROR 

隨着GCC-5.1誤差(與鐺類似)

error: call to 'foo' is ambiguous 
    foo(std::bind(ret_int)); 
    ^~~ 
note: candidate function 
void foo(std::function<void(int)>) {} 
    ^
note: candidate function 
void foo(std::function<int()>) {} 

然而所有以下的工作

foo(std::bind(take_int, _1)); 
foo(take_int); 

foo(ret_int); 
foo([](){ return ret_int(); }); 

struct TakeInt { 
    void operator()(int) const { } 
}; 

struct RetInt { 
    int operator()() const { return 0; } 
}; 

foo(TakeInt{}); 
foo(RetInt{}); 

望着std::function構造

template< class F > 
function(F f); 

它將使意義,我認爲對不同類型的std::function多個重載任何函數應該有歧義,但它僅與綁定的電話的問題。然後我想「也許有一些神奇的事情處理函數類型和lambda表達式,它不處理實際的類,」但它也處理這些。

有上en.cppreference一張紙條,上面寫着[因爲C++ 14]

此構造函數不參與重載解析,除非f是可贖回的參數類型參數數量...並返回類型R

+0

相關:http://stackoverflow.com/questions/30227097/c11-lambda-can-be-assigned-to-stdfunction-with-incorrect-signature和http://stackoverflow.com/questions/22146749/overload -resolution-with-stdfunction/22147471#22147471 – 0x499602D2

回答

4

問題在於如何允許調用綁定。 As cppreference states

如果在調用g()時提供的某些參數未與g中存儲的任何佔位符匹配,則會評估和丟棄未使用的參數。

換句話說,你需要通過至少儘可能多的參數作爲基礎函子的期望。

這意味着以下是有效

int f(); 
auto b = std::bind(f); 
b(1, 2, 3); // arguments aren't used 

因此說

auto b = std::bind(ret_int) 
b(1); 

工程,與所述1丟棄,因此以下是有效的,並且過載選擇變得曖昧

std::function<void(int)> f = std::bind(ret_int); 

反之亦然,但

std::function<int()> f = std::bind(take_int); 

因爲take_int不能用無參數調用。

外賣:拉姆達>綁定


此特定情況下,似乎C++ 14雖然

N4140 20.9.11.2.1/8

template<class F> function(F f);

破備註:除非參數類型爲ArgType的Callable,否則這些構造函數不應參與重載解析小號...和返回類型R

因爲ret_int當不帶參數調用不返回void

+0

在標準中,它是否表示多餘的參數被丟棄?我似乎無法找到它。 – 0x499602D2

+0

@ 0x499602D2我不知道我在這個cppreference上停了下來。我現在也在看 –

+0

我想我覺得它雖然看起來有點牽強附會:N4431 20.9.2/4。 '轉發調用包裝器是一個調用包裝器,可以用任意參數列表調用包裝器並將參數作爲參考傳遞給包裝後的可調用對象。該筆記甚至使用可變參數。 –

相關問題