2017-05-02 13 views
1

私はc++を初めて使っていますが、ジェネリックスの概念を理解するために過去の知識が十分にあります。私は何年もPython開発者でした。C++テンプレートの構文を理解する、typename

例では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); 
} 

私は誰かがコンパイルエラーを説明し、次の部分にいくつかの洞察を提供することができ、次のコマンドを使用して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)); 

からコンパイルするg++を使用しています:

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

templateキーワードを使用すると、関数は汎用イテレータを受け入れることができます。しかし、なぜこのコードファイル内のすべての関数で使用するためにヘッダファイルにグローバルtemplateを定義できないのですか?

+2

あなたは、少なくとも '-std = C++ '11でコンパイルする必要があります。 –

+4

私はあなたが 'typename'の代わりに' typename'の代わりに 'typedef'を使うと思っています:typename std :: vector :: value_type> TmpVec; – NathanOliver

+2

C++にはジェネリックがありません。 C++を書くときにJavaの観点から考えないでください。 –

答えて

2

std::make_move_iterator()はC++ 11で追加されましたので、あなたは彼のコメントを@NathanOliverに-std=c++98

0

感謝を使ってコンパイルすることはできません。下記コンパイルし、正しく実行されます。c++11先端ため@TriskalJMへ

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"; 
} 

ありがとう!

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