2011-01-21 59 views
5

我的問題代碼:C++超載:字符串常量與升壓::功能歧義

#include <string> 
#include <boost/function.hpp> 

void func (const std::string&) {} 
void func (const boost::function<void()>&) {} 

int main() { 
    func (main); // good 
    func ("bad"); 
    return 0; 
} 

=>

error: call of overloaded ‘func(const char [4])’ is ambiguous 
overload.cpp:4: note: candidates are: void func(const std::string&) 
overload.cpp:5: note:     void func(const boost::function<void()()>&) 

我知道我可以通過顯式調用FUNC(字符串(解決這個「壞「));或者通過提供一個func(const char *),但我想知道是否有一種方法來保持調用者方面的例子,並且不會引入更多的重載。

也許用boost :: enable_if做些什麼? 感謝您的任何提示。

+0

你真的認爲原因是需要`boost :: function`的重載,你有沒有嘗試編譯沒有超載?這會工作嗎? – Nim 2011-01-21 09:56:33

+1

是由boost :: function引起的。我發佈的例子重現了整個情況。 – denis 2011-01-21 10:04:52

+0

是啊 - 沒有測試之前詢問,只是有點困惑,這是這種情況 - 看起來像它是..嗯..缺少提供超負荷的一切,不知道有一個整潔的解決方案... – Nim 2011-01-21 10:18:43

回答

4

你不能輕易解決這個問題。 boost::function<>std::function<>不支持僅可由f()調用的函數,但也指向由(secondArg.*firstArg)()和數據成員調用的成員,因此它們的構造函數基本上都唾手可得,然後決定如何處理該類型。

寫這樣一個SFINAE測試類可以防止隱式轉換(我甚至不確定它是否完全可能,因爲標準庫沒有這樣做,這一點也不重要。一些原因)。請記住,由於許多不同的屬性,類型可能是可調用的 - 它可能具有函數指針類型等的轉換函數pp。編寫一個可以使其工作的SFINAE類意味着在某些情況下拒絕隱式轉換並接受隱式轉換其他案例基於真正不明顯的屬性。

如果你想避免這種不明確的地方,我會嘗試只選擇一個不同的函數名稱,或者如果它是一次性問題,在來電方進行投射。

0

補充一點:

void func (const char *s) { func(string(s)); } 

更新

template<class A0, ...> 
void func (const A0 &a0, ...) { 
    func(argize(a0), ...); // convert chars to strig, otherwise jut pass 
}