views:

86

answers:

1

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;
   }
 }
+3  A: 

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
It's usually better to parameterize on iterators than on containers. (Which is what OP is doing.)
Potatoswatter
@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
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
@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
Gijera
@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