Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Determine data type of items in an STL container in a template method

I’m trying to write a template method to handle items in an STL container. Getting details of the container is easy (and I use a std::enable_if clause to allow this template method to be called only if the container can be iterated over (detects a begin() method.)) I further need to know the data type held by the container. Here’s what works:

template <typename CONTAINER>
std::string doStuff(const CONTAINER & container) {
   using CONTAINER_TYPE = typename CONTAINER::value_type;
}

I can use if constexpr within this method to do certain things if I can also determine the type of the things held in the container. Here’s code that won’t work but is like what I’m trying for:

template <typename CONTAINER, typename ITEM>
std::string doStuff(const CONTAINER<ITEM> & container) {
   using CONTAINER_TYPE = typename CONTAINER::value_type;
   using ITEM_TYPE = typename ITEM::value_type;
}

It completely makes sense why I can’t invoke the method this way, but what could I do (either in invoking the method or with metaprogramming inside the method) to determine the type of the items in the container. I’d like to do it such that it is known at compile time.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

(I’ve tried a couple permutations of decltype and invoke_result and tons of searching but nothing is quite working yet.) I’ve tried for example:

using ITEM_TYPE = std::invoke_result<&CONTAINER::begin>::type;

Of course, that returns an iterator type which needs to be dereferenced but ‘*’ doesn’t seem to work as expected here.

>Solution :

You could use template template parameters:

template <template <class, class...> class CONTAINER, class ITEM, class... REST>
std::string doStuff(const CONTAINER<ITEM, REST...>& container) {
   using CONTAINER_TYPE = ITEM; // or `typename CONTAINER<ITEM, REST...>::value_type`
   // This requires SFINAE to not match `ITEM`s without `value_type`:
   using ITEM_TYPE = typename ITEM::value_type;

   //...
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading