2016-12-16 26 views
5

मैं एक अलग थ्रेडstd :: मर्ज std :: async

int main() 
{ 
    vector<int> a(100); 
    vector<int> b(100); 
    vector<int> c(200); 
    std::async(std::launch::async, std::merge, a.begin(), a.end(), b.begin(), 
       b.end(), 
       c.begin()); 
} 

में दो वैक्टर मर्ज करना चाहते हैं के साथ काम नहीं करता है यह

main.cpp: In function ‘int main()’: 
main.cpp:17:25: error: no matching function for call to ‘async(std::launch, <unresolved overloaded function type>, std::vector<int>::iterator, std::vector<int>::iterator, std::vector<int>::iterator, std::vector<int>::iterator, std::vector<int>::iterator)’ 
       c.begin()) 
         ^
In file included from main.cpp:4:0: 
/usr/include/c++/6.2.1/future:1709:5: note: candidate: template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_BoundArgs>::type ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) 
    async(launch __policy, _Fn&& __fn, _Args&&... __args) 
    ^~~~~ 
/usr/include/c++/6.2.1/future:1709:5: note: template argument deduction/substitution failed: 
main.cpp:17:25: note: couldn't deduce template parameter ‘_Fn’ 
       c.begin()) 
         ^
In file included from main.cpp:4:0: 
/usr/include/c++/6.2.1/future:1739:5: note: candidate: template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_BoundArgs>::type ...)>::type> std::async(_Fn&&, _Args&& ...) 
    async(_Fn&& __fn, _Args&&... __args) 
    ^~~~~ 
/usr/include/c++/6.2.1/future:1739:5: note: template argument deduction/substitution failed: 
/usr/include/c++/6.2.1/future: In substitution of ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_BoundArgs>::type ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = std::launch; _Args = {}]’: 
main.cpp:17:25: required from here 
/usr/include/c++/6.2.1/future:1739:5: error: no type named ‘type’ in ‘class std::result_of<std::launch()>’ 

संकलन नहीं है दूसरी ओर, अगर मैं

std::merge(a.begin(), a.end(), b.begin(), b.end(), c.begin()); 

सब कुछ ठीक काम करता है। अगर मैं लैम्ब्डा का भी उपयोग करता हूं।

क्यों?

उत्तर

10

std::mergeटेम्पलेट फ़ंक्शन है।

auto merger = [&a, &b, &c] 
{ 
    return std::merge(a.begin(), a.end(), b.begin(), b.end(), c.begin()); 
}; 

std::async(std::launch::async, merger); 

:

std::async(std::launch::async, 
      &std::merge<decltype(a.begin()), decltype(b.begin()), decltype(c.begin())>, 
      a.begin(), a.end(), b.begin(), 
      b.end(), 
      c.begin()); 

यहाँ एक लैम्ब्डा का प्रयोग शायद साफ और अधिक पठनीय समाधान है: एक टेम्पलेट समारोह के लिए सूचक हो रही है स्पष्ट रूप से निर्दिष्ट करने के लिए क्या टेम्पलेट पैरामीटर की आवश्यकता है सी ++ 14 में, आप सीधे std::async में तर्कों को पारित करने के लिए जेनेरिक लैम्ब्डा का उपयोग कर सकते हैं। (यह संदिग्ध है या नहीं यह कब्जा a, b, और c तुलना में एक बेहतर समाधान है।) उदाहरण:

auto merger = [](auto&&... xs) 
{ 
    return std::merge(std::forward<decltype(xs)>(xs)...); 
}; 

std::async(std::launch::async, merger, 
      a.begin(), a.end(), b.begin(), b.end(), c.begin()); 
+0

@NathanOliver: ओह, तुम सही हो - जवाब तय की। धन्यवाद। –

+0

@ किमी: ओपी के उदाहरण में केवल हल्के इटरेटर को 'std :: merge' में पास किया जाता है, इसलिए मैंने सही अग्रेषण जोड़ने में परेशान नहीं किया। पूर्व-निरीक्षण में, एक और सामान्य समाधान बेहतर है - मैं अपना उत्तर अपडेट करूंगा। –

+0

जैसा कि आप इसे 'std :: async' में पास कर रहे हैं और ये इटरेटर्स की प्रतिलिपि बनाने के लिए सस्ते हैं, मैं कैप्चर-बाय-वैल्यू का उपयोग संदर्भ में नहीं करता। – Yakk

संबंधित मुद्दे