2017-05-02 56 views
1

我是的新手,但我有足夠的知識從過去了解泛型的概念;多年來,我一直是一名Python開發人員。C++瞭解模板的語法,輸入名稱

我通過示例學習了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

你應該至少用'-std = C++ 11'進行編譯。 –

+4

我認爲你的意思是在'typename std :: vector :: value_type> TmpVec;' – NathanOliver

+2

中使用'typedef'而不是'typename'。C++沒有泛型。在編寫C++時不要用Java來思考。 –

回答

2

std::make_move_iterator()添加在C++ 11,所以你可以使用-std=c++98

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,