Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any generic type in C++ class

Is there a way in C++ to specify any type* as type of a template, for example through a wildcard or some keyword.

I remember in Java we can do that using the ? wildcard as generic type, like HashMap<Long, ?>.

I try to better explain the question using a sample code. Suppose we have the following Record class:

template<typename T>
class Record
{
    private:
        T content;
        long size;

    public:
        Record(T _content, long _size)
        {
            this->content = _content;
            this->size = _size;
        }

        T getContent()
        {
            return this->content;
        }

        long getSize()
        {
            return this->size;
        }
};

and suppose we want to use instances of the above class without specifying the exact type (I used the ? in the following class), simply because useless in the case in which the class Computer uses only the method Record::getSize():

class Computer
{
    public:
        long long computeTotalSize(vector<Record<?>> recordVector)
        {
            long long totalSize = 0;
            for (vector<Record<?>>::iterator it = recordVector.begin() ; it != recordVector.end(); ++it)
                totalSize += (*it).getSize();

            return totalSize;
        }
};
like image 888
PeppeMir Avatar asked Jan 12 '16 14:01

PeppeMir


People also ask

Is any a generic type?

extends Record<string, any> is known as generic type constraint, and it allows you to specify that your generic type must be assignable to the type that comes after the extends keyword. In this case, Record<string, any> indicates an object with keys of type string and values of type any .

Is there generics in C?

Generics are syntax components of a programming language that can be reused for different types of objects. Typically, generics take the form classes or functions, which take type(s) as a parameter.

Can generic class handle any type of data?

A generic class and a generic method can handle any type of data.

What is the generic class type called?

Generic Classes These classes are known as parameterized classes or parameterized types because they accept one or more parameters.


2 Answers

You can make computeTotalSize a template function with the record template parameter as it's template parameter:

template <typename T>
long long computeTotalSize(vector<Record<T>> recordVector)
{
    long long totalSize = 0;
    for (vector<Record<T>>::iterator it = recordVector.begin() ; it != recordVector.end(); ++it)
        totalSize += (*it).getSize();

        return totalSize;
}

Note that you should also pass the vector by reference to avoid copying the entire thing:

long long computeTotalSize(const vector<Record<T>>& recordVector)
like image 100
TartanLlama Avatar answered Oct 08 '22 02:10

TartanLlama


It cannot be done the same way as in Java, because C++ templates are fundamentally different from Java generics (C++ templates generate entirely distinct types, not fancy constructs on top a type-erased type). However, you could make computeTotalSize a function template:

class Computer
{
    public:
        template <class T>
        long long computeTotalSize(const vector<Record<T>>& recordVector)
        {
            long long totalSize = 0;
            for (auto it = recordVector.begin() ; it != recordVector.end(); ++it)
                totalSize += it->getSize();

            return totalSize;
        }
};

Notice I took the liberty of streamlining the syntax of the code somewhat; the only behaviour change is using const& to pass the vector, to prevent copying it.

Note that the change to const& requires getSize() to be marked as a const member function:

long getSize() const
{
    return size;
}

Since it would be highly unexpected for a function called getSize() to modify the object on which it's called, this is actually a good thing.

like image 27
Angew is no longer proud of SO Avatar answered Oct 08 '22 04:10

Angew is no longer proud of SO