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(¶llel_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>
In C++ this can be achieved using template parameters. A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.
Template parameters may have default arguments. The set of default template arguments accumulates over all declarations of a given template.
Class Template Argument Deduction (CTAD) is a C++17 Core Language feature that reduces code verbosity. C++17's Standard Library also supports CTAD, so after upgrading your toolset, you can take advantage of this new feature when using STL types like std::pair and std::vector.
A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With