2016-02-12 100 views
1

我想做出一些類的構造函數如下的兩個重載:歧義,因爲性病的構造函數重載::函數

foo(int, std::function<int(Tpoint, Tpoint)>); 
foo(int, std::function<int(Tpoint, Tpoint, std::vector<Tpoint>)>); 

當調用它,我得到了模糊問題。爲什麼?

foo<cv::Point> bar(2,[](cv::Point const& l, cv::Point const& r){ 
    return 5; 
}); 

目前尚不清楚,我需要的第一個構造函數在這裏,因爲它只有2 std::function參數。

編輯:

由於Lol4t0評論,它適用於其他編譯器。看來VS.NET的問題。 Example 1Example 2

我正在使用Microsoft Visual Studio 2013.任何人都可以重現嗎?

+1

我不認爲這應該與任何工作,因爲它不會返回一個'int'。 – Claudiu

+0

對不起,我忘了編輯它,而我簡化了它 –

+0

看起來對我來說http://ideone.com/qDeZKr – Lol4t0

回答

2

MSVC 2013 std::function只是一個C++ 11 std::function沒有額外的功能(如果我沒記錯的話)缺陷報告。

該附加特徵是該template<class F> function(F&&)構造是SFINAE狀限制爲僅工作在類型F使得function實際上可以從該類型構成。 (該標準沒有強制執行基於SFINAE的實現)

實際上,std::function有一個「嘗試從任何東西構造」的構造函數。如果發生故障,超負荷解決不會太晚。至少在MSVC2013中。所以你的std::function看起來像有效的重載。

我相信2015年的最新版本有std::function有限能力做你要求的超負荷。

在2013年,您可以採取一種可行的解決方法,但這很痛苦。

首先,學習如何重載函數對象的集合。然後,創建一個函數對象F和另一個需要Tpoint, Tpoint並返回some_special_tag_type的函數對象的重載集。現在,將Tpoint, Tpoint傳遞給該過載集,並跟蹤返回類型是否爲some_special_tag_type。將該決定從foo(int, F&&)過載標籤發送到foo_impl(tag_1, int, std::function<blah_1>)foo_impl(tag_2, int, std::function<blah_2>)

只升級到MSVC2015或者不依賴重載可能更容易。

請注意,如果您在返回類型而不是參數類型上重載,此技術實際上是可行的。這很難,因爲即使MSVC2015也沒有「表達SFINAE」,這削弱了這種元編程。