C++ wrong number of template arguments (2, should be 1)

匿名 (未验证) 提交于 2019-12-03 08:59:04

问题:

I did a test with c++ parallel quicksort program as below first with list as container then I moved to a generic container type, but it reported the captioned error.

Can help with this?

#include <iostream>     // std::cout #include <future>       // std::packaged_task, std::future #include <chrono>       // std::chrono::seconds #include <thread>       // std::thread, std::this_thread::sleep_for #include <list> #include <algorithm> #include <type_traits> #include <iterator>  template<typename F, typename A> static std::future<typename std::result_of<F(A&&)>::type> spawn_task(F&& f, A&& a) {     typedef typename std::result_of<F(A&&)>::type result_type;      std::packaged_task<result_type(A&&)> task(std::move(f));     std::future<result_type> res(task.get_future());     std::thread myThread(std::move(task), std::move(a));     myThread.detach();     return res; }  template<class T, template<class T> class Container>  static Container<T> parallel_quick_sort(Container<T> input) {     if (input.empty())     {         return input;     }      Container<T> result;     result.splice(result.begin(), input, input.begin());     T const& partition_val = *result.begin();      typename Container<T>::iterator divide_point = std::partition     (input.begin(), input.end(), [&](T const& t)         {          return t<partition_val;         }     );      Container<T> lower_part;     lower_part.splice(lower_part.end(), input, input.begin(), divide_point);      std::future<Container<T> > new_lower     (         spawn_task(&parallel_quick_sort<T>, std::move(lower_part))     );     Container<T> new_higher(parallel_quick_sort(std::move(input)));     result.splice(result.end(), new_higher);     result.splice(result.begin(), new_lower.get());      return result; }   static void testQuickSort() {     std::list<int> toSort={1, 4, 3, 6, 4, 89, 3};     std::for_each     (             std::begin(toSort), std::end(toSort), [](int n)         {             std::cout << n << std::endl;         }     );      std::list<int> sorted;     sorted = parallel_quick_sort(toSort);     std::for_each     (         std::begin(sorted), std::end(sorted), [](int n)         {             std::cout << n << std::endl;         }     ); } 

The error message is:

../src/TestGenericQuickSort.h: In static member function ‘static void TestGenericQuickSort::testQuickSort()’:

../src/TestGenericQuickSort.h:67:41: error: no matching function for call to ‘TestGenericQuickSort::parallel_quick_sort(std::list&)’ sorted=parallel_quick_sort(toSort);

../src/TestGenericQuickSort.h:67:41: note: candidate is:

../src/TestGenericQuickSort.h:33:22: note: template class Container> static Container TestGenericQuickSort::parallel_quick_sort(Container) static Container parallel_quick_sort(Container input)

../src/TestGenericQuickSort.h:33:22: note: template argument deduction/substitution failed:

../src/TestGenericQuickSort.h:67:41: error: wrong number of template arguments (2, should be 1) sorted=parallel_quick_sort(toSort);

../src/TestGenericQuickSort.h:32:44: error: provided for ‘template class Container’ template class Container>

回答1:

You pass a std::list, whose full declaration is

template <typename T, typename Alloc = std::allocator<T> > class list; 

So, it has 2 template parameters, though the seconds one has a default value (and that's the reason why you don't see it).

A better design would be to pass 2 input iterators and an output iterator to your function:

template <typename IteratorIn, typename IteratorOut> static IteratorOut parallel_quick_sort(IteratorIn begin, IteratorIn end, IteratorOut out); 

See std::sort for more details on this signature.



回答2:

First I need to thank lisyarus for the answer, without it I couldn't work things out as below.

But since this is an exercise about the inner workings of C++, I tried to modify my own code to make it work and finally it worked as below.

#include <iostream>     // std::cout #include <future>       // std::packaged_task, std::future #include <chrono>       // std::chrono::seconds #include <thread>       // std::thread, std::this_thread::sleep_for #include <list> #include <algorithm> #include <type_traits> #include <iterator>  template<typename F, typename A> static std::future<typename std::result_of<F(A&&)>::type> spawn_task(F&& f, A&& a) {     typedef typename std::result_of<F(A&&)>::type result_type;     std::packaged_task<result_type(A&&)> task(std::move(f));     std::future<result_type> res(task.get_future());     std::thread myThread(std::move(task), std::move(a));     myThread.detach();     return res; } template<class T, class Alloc, template<class T, class Alloc> class Container> static Container<T, Alloc> parallel_quick_sort(Container<T, Alloc> input) {     if (input.empty())     {         return input;     }      Container<T, Alloc> result;     result.splice(result.begin(), input, input.begin());     T const& partition_val = *result.begin();     typename Container<T, Alloc>::iterator divide_point = std::partition(             input.begin(), input.end(), [&](T const& t)             {   return t<partition_val;});     Container<T, Alloc> lower_part;     lower_part.splice(lower_part.end(), input, input.begin(), divide_point);       std::future<Container<T, Alloc> > new_lower(             spawn_task(&parallel_quick_sort<T, Alloc, Container>, std::move(lower_part)));      Container<T, Alloc> new_higher(parallel_quick_sort(std::move(input)));     result.splice(result.end(), new_higher);     result.splice(result.begin(), new_lower.get());     return result;  }    static void testQuickSort() {     std::list<int> toSort={1,4,3,6,4,89,3};     std::for_each(std::begin(toSort), std::end(toSort), [](int n){ std::cout << n << std::endl;});     std::list<int> sorted;     sorted=parallel_quick_sort(toSort);     std::for_each(std::begin(sorted), std::end(sorted), [](int n){ std::cout << n << std::endl;});   } 

Thank you for all your help!!!



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!