【问题标题】:C++ wrong number of template arguments (2, should be 1)C++ 模板参数的数量错误(2,应该是 1)
【发布时间】:2014-02-28 14:00:58
【问题描述】:

我首先使用以下 c++ 并行快速排序程序进行了测试,其中列表作为容器,然后我移至通用容器类型,但它报告了标题错误。

可以帮忙吗?

#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;
        }
    );
}

错误信息是:

../src/TestGenericQuickSort.h:在静态成员函数'static void TestGenericQuickSort::testQuickSort()'中:

../src/TestGenericQuickSort.h:67:41:错误:没有匹配函数调用‘TestGenericQuickSort::parallel_quick_sort(std::list&)’ sorted=parallel_quick_sort(toSort);

../src/TestGenericQuickSort.h:67:41:注意:候选人是:

../src/TestGenericQuickSort.h:33:22: 注意:模板类 Container> static Container TestGenericQuickSort::parallel_quick_sort(Container) static Container parallel_quick_sort(Container input)

../src/TestGenericQuickSort.h:33:22:注意:模板参数推导/替换失败:

../src/TestGenericQuickSort.h:67:41: 错误:模板参数的数量错误(2,应该是 1) sorted=parallel_quick_sort(toSort);

../src/TestGenericQuickSort.h:32:44: 错误:为‘模板类容器’提供模板类容器>

【问题讨论】:

标签: c++ templates


【解决方案1】:

你传递了一个std::list,它的完整声明是

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

所以,它有 2 个模板参数,虽然 seconds 有一个默认值(这就是你看不到它的原因)。

更好的设计是将 2 个输入迭代器和一个输出迭代器传递给您的函数:

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

有关此签名的更多详细信息,请参阅std::sort

【讨论】:

  • 当心,InputIterator 意味着一旦你消费了其中的一个元素,你就无法再次获得它。它不适合作为排序函数的迭代器。想一想只从一个方向读取磁带。为了清楚起见,你想说ForwardIterator
  • @mockinterface:在我的代码中InputIterator 没有命名迭代器类别,只是它的语义。考虑到快速排序功能,这里RandomAccessIterator 会更好吗?
  • 是的,我当然明白你没有将其命名为迭代器类别,但最好严格一点,因为InputIterator在标准中有具体含义。关于 ForwardRandom - 这取决于排序实现的基本要求,但两者都比 Input 好。考虑IteratorIn / IteratorOut
  • @mockinterface:我同意,InputIterator 在这种情况下会使签名变得混乱。
  • 非常感谢您的回答!!
【解决方案2】:

首先我要感谢 lisyarus 的回答,没有它我无法解决以下问题。

但由于这是一个关于 C++ 内部工作原理的练习,我尝试修改自己的代码以使其工作,最后它工作如下。

#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;});


}

感谢大家的帮助!!!

【讨论】:

  • 我尝试了vector然后失败了,因为vector没有拼接功能,所以现在这不是一个通用功能。以后会努力做一个...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-27
  • 2017-10-10
  • 2012-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多