c++templates

template class to manage containers, getting type of contained data


I have a templated c++ class which acts on containers. In the class implementation I need access to the type of the data the container contains. I've currently defined it like this:

template <typename ContainerType, typename DataType>
class MyClass {
    DataType a;
    DataType foo(DataVector& vec, DataType s);
};

And when I instantiate it I instantiate it like this

MyClass< vector<float>, float > c1;
MyClass< CustomVector<double>, double > c2;
MyClass< Lib::ContainerFloat, Lib::Float > c3; 

This works, but is there a way of doing this without duplicating the type info (i.e. float, double etc)? I.e. use some decltype-like magic to get the contained data type. So I'd like to be able to instantiate with:

MyClass< vector<float> > c1;
MyClass< CustomVector<double> > c2;
MyClass< Lib::ContainerFloat > c3; 

and declare the class with:

template <typename ContainerType>
class MyClass {
    // get DataType automatically from ContainerType
    DataType a;
    DataType foo(DataVector& vec, DataType s);
};

Solution

  • As a concept, all containers are expected to support value_type as a type. See http://en.cppreference.com/w/cpp/concept/Container.

    Last I checked, value_type is supported by:

    1. std::vector
    2. std::list
    3. std::set
    4. std::multiset
    5. std::unordered_set
    6. std::unordered_multiset
    7. std::queue
    8. std::array
    9. std::map
    10. std::unordered_map
    11. std::unordered_multimap
    12. std::multimap
    13. std::stack
    14. std::priority_queue

    I think it's safe for you to use:

    template <typename ContainerType>
    class MyClass {
       using DataType = ContainerType::value_type;
    };
    
    MyClass< vector<float>> c1;
    

    If DataType can ever be different than ContainerType::value_type, it will be better to use (Thanks are due to @AlexeyAndronov for the suggestion):

    template <typename ContainerType,
              typename DataType = ContainerType::value_type>
    class MyClass {
    };