2016-01-01 14 views
7

mi si avvicinò con il seguente:Passare un contenitore std a una funzione

template <typename T> inline void printcontainer(std::vector<T> container) 
{ 
    for(auto it = container.begin(); it != container.end(); it++) 
    { 
     std::cout << *it << std::endl; 
    } 
} 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    std::vector<int> v; 
    v.push_back(5); 
    v.push_back(4); 
    v.push_back(3); 
    printcontainer(v); 

    return 0; 
} 

(Ci scusiamo per l'push_backs, Visual Studio non accetta liste di inizializzazione ... ugh !!)

ora questa funzione è limitata a std::vector, come posso fare in modo che possa passare altri contenitori, come gli array std::list ecc.

+0

Quale versione di VC++ stai usando che non supporta gli elenchi di inizializzazione? – MikeMB

+0

visual studio 2012, cose come 'std :: vector v {1,2,3};' non è supportato, quindi è necessario utilizzare la soluzione di array in stile c che io disprezzo abbastanza. Inoltre non ha 'std :: initializer_list' piuttosto strano eh. –

+0

Esatto, sono diventato così abituato al C++ 11 che ho dimenticato che VS ha adottato molti/più? Funzionalità di C++ 11 non prima di VS 2013. – MikeMB

risposta

7

Semplicemente non modello sul tipo memorizzato dal contenitore, ma sul tipo di contenitore stesso:

template <typename Container> 
inline void printcontainer(const Container &container) 

Nota che ho modificato l'argomento al riferimento const per evitare una copia non necessaria.

È possibile allargare la funzione di stampa a matrici C utilizzando il non-membro std::begin e std::end o utilizzando un range based for loop:

template <typename Container> 
inline void printcontainer(const Container &container) { 
    for (const auto &v : container) 
     std::cout << v << "\n"; 
} 

OT osservazione: Probabilmente non è necessario il inline qui.

+0

wow sono molto impressionato da 'for (const auto & v: container)' come si chiama? Lo studierò –

+2

[Range-based for loop (dal C++ 11)] (http://en.cppreference.com/w/cpp/language/range-for) – Drop

+0

tyvm, accetterò questa risposta non appena lo consente! –

2

Il passaggio degli oggetti contenitore è contro il classico STL algoritmo del contenitore-iteratore Stile di programmazione generico.

Di solito si passerebbe iteratori:

# define ForwardIterator typename // workaround untill we have concepts 

template <ForwardIterator It> inline void printcontainer(It begin, It end) 
{ 
    for(;begin != end; ++begin) 
    { 
     std::cout << *begin << std::endl; 
    } 
} 

Usage:

std::vector<int> v = {1, 2, 3, 4}; 
printcontainer(v.cbegin(), v.cend()); 
+0

* "Stai provando a scrivere Java nei file C++." * In che modo? Non vedo alcun problema con il passaggio del contenitore qui.Infatti, boost fornisce molte versioni container delle funzioni basate su iteratore nella libreria standard per ridurre la verbosità. (Non è il mio dv btw.) –

+0

@BaummitAugen Okay, era un po 'troppo, rimuoverò questa frase;) – Drop

+1

Mentre questo sembra OK, quella macro è semplicemente orribile e merita un downvote tutto da solo. Inoltre, avvitare gli iteratori, le gamme sono il futuro. – Puppy

Problemi correlati