2017-04-12 81 views
0

我有一個類有兩個重載成員。一個接受一個整數,另一個接受一個參數的模板函數。演員未解決模板重載類成員

class MyClass 
{ 
    public: 
     void doSomething(int data){ std::cerr << data;} 
     template <typename T> doSomething(T &&data){ std::cerr << data;} 
}; 

我想這個功能

MyClass myobject; 
auto my_bind = std::bind(&MyClass::doSomething, &myobject, 2); 
my_bind(); 

綁定但這不會編譯因爲編譯器不能扣除調用哪個函數。

error: no matching function for call to 'bind(unresolved overloaded function type, MyClass*, int)'

我明白我必須施放這個功能。

auto my_bind2 = std::bind(static_cast<void (MyClass::*)(int)>(&MyClass::doSomething), &myobject, 2); 

現在它編譯和按預期工作。

但是如果我想將它與任何其他參數綁定來調用模板函數呢?這甚至有可能嗎?我找不到語法。

這不起作用:

auto my_bind3 = std::bind(static_cast<void (MyClass::*)(std::string)>(&MyClass::doSomething), &myobject, std::string("Hello")); 

我想避免使用lambda表達式。我簡化了MCVE的代碼,但在實際的代碼中,我應該使用成員指針。

感謝您的幫助

+0

* 「我想避免使用lambda表達式。」 * - 你喜歡困難的方式? – WhiZTiM

回答

1

您應該簡單地提供成員函數模板的相關實例的地址:

auto my_bind3 = std::bind(&MyClass::doSomething<std::string&>, &myobject, std::string("Hello")); 
           //Note the reference here ^^ 

上述工作,因爲std::bind會將它的參數,並自doSomething成員函數模板採用其參數轉發參考,我們需要利用參考摺疊。

雖然有點像下面的代碼片段將「綁定」,

auto my_bind3 = std::bind(&MyClass::doSomething<std::string>, &myobject, std::string("Hello")); 
        //Note the absence of a reference here ^^ 

它是要失敗的,當你最終調用my_bind3()

Demo


如果你可以使用lambda,使用它,因爲完美forwading將在踢

auto my_bind4 = [&myobject](){ myobject.doSomething(std::string("\nHullo")); }; 
+0

那麼這比我想象的要容易...所以即使函數需要引用,參數實際上是複製的嗎?我不明白爲什麼第二個不起作用。 – dydil

+1

@dydil,['std :: bind'](http://en.cppreference.com/w/cpp/utility/functional/bind)總是**將其參數複製到它返回的對象中。當你調用返回對象的'operator(...)'時,已存**的**參數被傳遞給* bound *函數。請注意,'std :: bind'不會改變有界函數的語義。 (當「有界」函數是另一個「std :: bind」時,這是一個例外) – WhiZTiM

+1

第二次失敗,因爲這個實例化將導致一個函數像'void doSomthing(std :: string && data)'。但是當你調用「std :: bind對象」時,它會通過值傳遞存儲的參數,它不會通過調用'std :: move(...)'將其轉換爲「rvalue」。這失敗了,因爲實例化需要一個「右值」。另一方面,第一種情況的作用是因爲它會創建一個像'void doSomthing(std :: string &&& data)'這樣的函數,並且通過引用合併規則,它會變成'void doSomthing(std :: string&data)'。這將很好地與'std :: bind'搭配使用 – WhiZTiM