2012-05-16 70 views
10

std::async可以使用模板函數嗎?我試圖將std::reverse作爲一個異步任務BU得到編譯時錯誤。std :: async可以與模板函數一起使用

我試過使用更簡單的函數(foo和bar),並發現只有非模板函數正在工作。

#include <algorithm> 
#include <future> 
#include <string> 

void foo(std::string::iterator first, std::string::iterator last) 
{ 
} 

template<class BidirectionalIterator> 
void bar(BidirectionalIterator first, BidirectionalIterator last) 
{ 
} 

int main() 
{ 
    std::string str = "Lorem ipsum, dolor sit amet"; 

    auto result_reverse = std::async(std::reverse, str.begin(), str.end()); // Compile-time error 
    auto result_foo  = std::async(foo, str.begin(), str.end()); 
    auto result_bar  = std::async(bar, str.begin(), str.end()); // Compile-time error 

    result_reverse.get(); 
    result_foo.get(); 
    result_bar.get(); 
} 

編譯器錯誤是如下:

main.cpp: In function ‘int main()’: 
main.cpp:18:71: erreur: no matching function for call to ‘async(<unresolved overloaded function type>, std::basic_string<char>::iterator, std::basic_string<char>::iterator)’ 
main.cpp:18:71: note: candidates are: 
/usr/include/c++/4.6/future:1355:5: note: template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) 
/usr/include/c++/4.6/future:1378:5: note: template<class _Fn, class ... _Args> typename std::__async_sfinae_helper<typename std::decay<_Functor>::type, _Fn, _Args ...>::type std::async(_Fn&&, _Args&& ...) 
main.cpp:18:71: erreur: unable to deduce ‘auto’ from ‘<expression error>’ 
main.cpp:20:62: erreur: no matching function for call to ‘async(<unresolved overloaded function type>, std::basic_string<char>::iterator, std::basic_string<char>::iterator)’ 
main.cpp:20:62: note: candidates are: 
/usr/include/c++/4.6/future:1355:5: note: template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) 
/usr/include/c++/4.6/future:1378:5: note: template<class _Fn, class ... _Args> typename std::__async_sfinae_helper<typename std::decay<_Functor>::type, _Fn, _Args ...>::type std::async(_Fn&&, _Args&& ...) 
main.cpp:20:62: erreur: unable to deduce ‘auto’ from ‘<expression error>’ 

然而,它傳遞的時候我手動指定模板instanciation,如std::async(std::reverse<std::string::iterator>, str.begin(), str.end())

這是一個編譯器錯誤(GCC 4.6.3)還是定義良好的行爲?

+4

模板是沒有的功能,所以其行爲依據的標準是正確的。如果你想推導出參數,你需要將它包裝在仿函數中。 – Xeo

回答

13

它可以,但調用是有點不同:

auto result_reverse = std::async([&str]() { 
     std::reverse(str.begin(), str.end()); 
    }); 

這是因爲std::reverse()不是一個函數,而當它被調用的函數,它變成一個功能的函數模板。

上面反轉了字符串的副本並丟棄了結果。要通過引用傳遞字符串,應將lambda表達式更改爲以[&str]()開頭。

+1

+1,但是這基本上什麼都不做,你應該通過引用傳遞'str'。 – KillianDS

+0

你說得對,它會顛倒一個字符串的副本並丟棄結果。我認爲這只是使用函數模板的一個例子。 –

+0

爲什麼lambda參數列表和它的正文之間有一個可變關鍵字? – authchir

6

std::reverse不是功能,而是一個函數模板,你可以使用該模板的特化(這是一個功能):

auto result_reverse = std::async(&std::reverse<std::string::iterator>, str.begin(), str.end()); 
+0

我不認爲'&'是強制性的......是嗎? –

+1

@MatthieuM。不,這個函數的名字會隱含地衰減成一個指向這個上下文的函數。我仍然更願意在處理函數指針時明確地要求它......荒謬的,因爲我不這樣做,因爲array-> pointer decay ... –

相關問題