c ++理解模板的语法,typename

时间:2017-05-02 16:01:13

标签: c++ templates generics

我是c++的新手,但我有足够的Java过去的知识来理解仿制药的概念;我已经成为python dev多年了。

我正在通过示例学习c++,我发现了这段代码,用于merge sort的泛型实现。

template<typename I>
void doMerge(I begin, I midPoint, I end)
{
    typename std::vector<typename std::iterator_traits<I>::value_type> TmpVec;

    TmpVec tmp(std::make_move_iterator(begin), std::make_move_iterator(end));

    TmpVec::iterator   beginAlt   = std::begin(tmp);
    TmpVec::iterator   endAlt     = std::end(tmp);
    TmpVec::iterator   midAlt     = std::next(beginAlt, std::distance(begin, midPoint));


    TmpVec::iterator   l   = beginAlt
    TmpVec::iterator   r   = midAlt;
    I                  i   = begin;

    while(l < midAlt && r < endAlt)
    {
        *i = std::move((*l < *r) ? *l++ : *r++);
        ++i;
    }
    while(l < midAlt)
    {   *i  = std::move(*l++);
        ++i;
    }
    while(r < endAlt)
    {   *i  = std::move(*r++);
        ++i;
    }
}
template<typename I>
void mergeSort(I begin, I end)
{
    std::size_t length  = std::distance(begin, end);
    if (length <= 1)
    {   return;
    }

    std::size_t mid      = length/2;
    I           midPoint = std::next(begin, mid);

    mergeSort(begin, midPoint);
    mergeSort(midPoint, end);

    doMerge(begin, midPoint, end);
}

我正在使用g++使用以下命令从Makefile进行编译

g++ -std=c++98 merge_sort.cpp -o mergesort.out

merge_sort.cpp:34:11: error: expected ';' after expression
    TmpVec tmp(std::make_move_iterator(begin), std::make_move_iterator(end));

有人可以解释编译错误并提供以下部分的一些见解:

template<typename I>
void doMerge(I begin, I midPoint, I end)

template关键字允许函数接受通用迭代器,对吗?但为什么我不能在头文件中定义一个全局template以用于此代码文件中的所有函数?

2 个答案:

答案 0 :(得分:2)

在C ++ 11中添加了

std::make_move_iterator(),因此您无法使用-std=c++98进行编译

答案 1 :(得分:0)

感谢@NathanOliver的评论。以下编译并正确执行:

template<typename I>
void doMerge(I begin, I midPoint, I end)
{
    typedef std::vector<typename std::iterator_traits<I>::value_type> TmpVec;

    TmpVec tmp(std::make_move_iterator(begin), std::make_move_iterator(end));

    typename TmpVec::iterator   beginAlt   = std::begin(tmp);
    typename TmpVec::iterator   endAlt     = std::end(tmp);
    typename TmpVec::iterator   midAlt     = std::next(beginAlt, std::distance(begin, midPoint));


    typename TmpVec::iterator   l   = beginAlt;
    typename TmpVec::iterator   r   = midAlt;
    I                  i   = begin;

    while(l < midAlt && r < endAlt)
    {
        *i = std::move((*l < *r) ? *l++ : *r++);
        ++i;
    }
    while(l < midAlt)
    {   *i  = std::move(*l++);
        ++i;
    }
    while(r < endAlt)
    {   *i  = std::move(*r++);
        ++i;
    }
}
template<typename I>
void mergeSort(I begin, I end)
{
    std::size_t length  = std::distance(begin, end);
    if (length <= 1)
    {   return;
    }

    std::size_t mid      = length/2;
    I           midPoint = std::next(begin, mid);

    mergeSort(begin, midPoint);
    mergeSort(midPoint, end);

    doMerge(begin, midPoint, end);
}


int main()
{
    std::vector<int>    data  {{ 5,12,45,2,67,8}};
    mergeSort(std::begin(data), std::end(data));

    std::copy(std::begin(data), std::end(data), std::ostream_iterator<int>(std::cout, ", "));
    std::cout << "\n";
}

感谢@TriskalJM提供的c++11小费!

$ make
rm -rf *.out
g++ -std=c++11 merge_sort.cpp -o mergesort.out
./mergesort.out
2, 5, 8, 12, 45, 67,