3

I want to be able to create a function where I specify a parameter to have both a templated container and a templated element type for that container. Is this possible? I get "error C2988: unrecongnizable template declaration/definition" among others. Here is the function in question.

template<class Iter, class Elem>
 void readIntoP(Iter<Elem> aCont){
ifstream ifss("data.dat");
string aString;
int counter = 0;
item tempItem;
while(ifss >> aString){
    istringstream iss(aString);
    if(counter == 0){
        tempItem.name = aString;
    }else if(counter == 1){
        int aNum = 0;
        iss >> aNum;
        tempItem.iid = aNum;
    }else{
        double aNum = 0;
        iss >> aNum;
        tempItem.value = aNum;
        aCont.push_back(tempItem);
        counter = -1;
    }
    ++counter;
   }
 }
Evan Sevy
  • 659
  • 1
  • 13
  • 25
  • 1
    Sort-of duplicate of [c++ function template compiles error "‘containerType’ is not a template"](http://stackoverflow.com/questions/3436518/c-function-template-compiles-error-containertype-is-not-a-template) (the solution is exactly the same, at least). – James McNellis Aug 11 '10 at 00:03
  • Related: [check type of element in stl container - c++ - Stack Overflow](https://stackoverflow.com/questions/1708867/check-type-of-element-in-stl-container-c) – user202729 Feb 16 '21 at 16:01

1 Answers1

5

You would need to use a template template parameter, e.g.,

template <template <class> class Iter, class Elem>
void readIntoP(Iter<Elem> aCont) { /* ... */ }

Note, however, that the standard library containers take multiple template parameters (vector, for example, takes two: one for the value type to be stored and one for the allocator to use).

You might instead use a single template parameter for the instantiated container type and then use its value_type typedef:

template <typename ContainerT>
void readIntoP(ContainerT aCont)
{
    typedef typename ContainerT::value_type ElementT;
    // use ContainerT and ElementT
}
James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • It's usually better to parameterize on iterators than on containers. (Which is what OP is doing.) – Potatoswatter Aug 11 '10 at 02:44
  • @Potatoswatter: It's hard to tell. The question title and variable name imply the OP is attempting to pass a container; the typename implies the OP is attempting to pass an iterator of some sort. Either way, iterators also have a `value_type` typedef. I'd agree that in general it is better to pass iterators around instead of containers, but often it is useful to pass a whole container. – James McNellis Aug 11 '10 at 02:50
  • I've heard that the standard doesn't specify how many parameters a container has. A vector has at least two, but implementation may add more for their own purposes, making "template templates" less portable? – UncleBens Aug 11 '10 at 06:55
  • @UncleBens: Johannes Schaub asked [a question about that](http://stackoverflow.com/questions/1469743/standard-library-containers-with-additional-optional-template-parameters) and the answer was that the standard does specify exactly what the parameters of a container must be – James McNellis Aug 11 '10 at 13:52
  • @James McNellis -> Could you describe the understanding of how the template parameter 'template class Iter' works (I'm having trouble following the logic). Also, I'm interested, why is parameterizing on iterators better than on containers? btw, thanks for all your extremely quick answers! :d P.S. @James McNellis & Potatoswatter -> Sorry about the misunderstanding with my template being called 'iter'. I was at first going to go the iterator route, but then decided to try this container route, but forgot to change it appropriatly. – Evan Sevy Aug 11 '10 at 18:25
  • @Gijera: A template template parameter allows you to instantiate a template with a template as its argument instead of with a type as its argument. So, in my example, you could instantiate `readIntoP` with any template that itself has a single template parameter. For more information, I'd recommend picking up a copy of _C++ Templates: The Complete Guide_, which is the definitive book on the workings of C++ templates. As for why iterators are better than containers: they add an extra layer of abstraction and let you deal with ranges of values more generically. – James McNellis Aug 11 '10 at 18:32