2011-06-19 14 views
6

イテレータとジェネリック関数をよりよく保持しようとしています。私はcontainer1 < container2 <type> >container3 <type>に変換する関数を書いておくと便利だと思いました。たとえば、vector< deque<int> >list<int>に変換する必要があります。コンテナのコンテナをフラット化する汎用関数

すべてのコンテナのアクセスは、<algorithm>の関数のように、イテレータを使用する必要があると考えました。ここで

私のコードです:

#include <iterator> 
#include <algorithm> 

// COCiter == Container of Containers Iterator 
// Oiter == Output Iterator 
template <class COCiter, class Oiter> 
void flatten (COCiter start, COCiter end, Oiter dest) 
{ 
    using namespace std; 

    while (start != end) { 
     dest = copy(start->begin(), start()->end(), dest); 
     ++start; 
    } 
} 

しかし、私は次のコードでそれを呼び出すようにしてみてください。

int main() 
{ 
    using namespace std; 

    vector< vector<string> > splitlines; 
    vector<string> flat; 

    /* some code to fill SPLITLINES with vectors of strings */ 

    flatten(splitlines.begin(), splitlines.end(), back_inserter(flat)); 
} 

私は巨大なC++テンプレート・エラー・メッセージを取得し、undefined reference to void flatten< ... pages of templates ...

私は私のコードは書くのが簡単すぎるように感じます。内側のコンテナのデータ型が出力コンテナのデータ型と確実に一致するようにするには、もっと多くのものが必要です。しかし、私は何をすべきかわかりません。

+0

スタックにはイテレーターがなく、開始/終了機能はありません。あなたがスタックで動作するようにしたいのであれば、それは特別なケースでなければなりません。 –

+0

これは本当です。私は質問を変えます。私は実際にスタックの互換性は必要ありません。ちょうど反復可能なコンテナ。 – japreiss

答えて

8

問題が見つかりました。 SFINAEのおかげで、(恐らくタイプミス)と入力してstartoperator()を呼び出そうとしているので、コンパイラは正しいテンプレートを見つけることができませんでした(代替失敗はエラーではありません)。これを試してください:

#include <iterator> 
#include <algorithm> 

// COCiter == Container of Containers Iterator 
// Oiter == Output Iterator 
template <class COCiter, class Oiter> 
void flatten (COCiter start, COCiter end, Oiter dest) { 
    while (start != end) { 
     dest = std::copy(start->begin(), start->end(), dest); 
     ++start; 
    } 
} 
+0

SFINAEは、関数の本体で発生する置換の失敗に対しては機能しません。これは関数のシグネチャ(戻り値の型とパラメータ)でのみ機能します。 –

+0

しかし、あなたの修正の作品:) –

+0

それは確かにタイプミスでしたが、私はまた、私のジェネリック関数のプロトタイプをヘッダーファイルに含めるのエラーをしていたことが判明した。私はあなたがそれをすることができないことを知りました。あなたはcppファイル全体を含める必要があります(私は思う)。 – japreiss

関連する問題