2011-06-19 17 views
6

Yineleyiciler ve genel işlevler üzerinde daha iyi bir tutmaya çalışıyorum. container1 < container2 <type> >'u container3 <type>'a dönüştüren bir işlev yazmak için yararlı bir egzersiz olacağını düşündüm. Örneğin, vector< deque<int> >'u list<int>'a dönüştürebilmelidir. Kapsayıcıların kabını düzleştirmek için genel işlev

Bütün konteyner erişim <algorithm> işlevler gibi yineleyicileri üzerinden diye düşünüyordum. İşte

benim kodudur:
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)); 
} 

Ben büyük C++ şablon hata mesajı undefined reference to void flatten< ... pages of templates ...

I:

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

Ama şu kodda diyoruz çalıştığınızda Kodumun yazılması çok kolaydı ve iç kaplardaki veri tipinin çıktı kabındaki veri tipiyle eşleştiğinden emin olmak için biraz daha fazla bilgiye ihtiyacım var. Ama ne yapacağımı bilmiyorum.

+0

Not o yığın yineleyicinızı yoktur ve hiçbir/bitiş fonksiyonları başlar. Yığınlarla çalışmak istiyorsanız, kesinlikle bunun için özel bir vakaya sahip olacaksınız. –

+0

Bu doğru; Soruyu değiştireceğim. Aslında yığın uyumluluğuna ihtiyacım yok; sadece tekrarlanabilir kaplar. – japreiss

cevap

8

Sorunu buldum. SFINAE (Yerine koyma hatası bir hata değildir) sayesinde, start() yazarak (muhtemelen bir yazım hatası) operator() numarasını operator() aramaya çalıştığınız için derleyiciniz doğru şablonu bulamadı. Bu deneyin:

#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, işlev gövdesinde oluşabilecek ikame arızaları için çalışmaz. Sadece fonksiyon imzasında çalışır (dönüş tipi ve parametreler). –

+0

Ancak, düzeltme işleminiz çalışıyor :) –

+0

Bu gerçekten bir yazım hatasıydı, ancak aynı zamanda bir genel dosyada benim genel işlev prototipimi ekleme hatası yaptığım ortaya çıktı. Sadece bunu yapamayacağınızı öğrendim; tüm cpp dosyasını dahil etmeliyim (bence). – japreiss

İlgili konular