Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accepting any type of STL container and using its value type

I have a function that operates on an STL container of any type and needs to the pass the container's element type to another template function. Actually, when I say any container type I don't really mean it. Strictly only vectors and arrays. I have something like this:

template <typename T> int ProcessData(T data)
{
  return DoInternalProcessing<T::value_type>(data.data(), data.size());
}

MSVC11 accepts this code but gcc does not. What's wrong with it? For gcc I thought about also having the value type be a parameter but then that would require the caller to specify T (the container type) which would be very unwieldy with std::array and this function's primary purpose is to provide a very simple interface that abstracts away from the underlying data.

like image 909
akai Avatar asked Mar 24 '23 20:03

akai


1 Answers

Since T::value_type is a dependent type, you need typename T::value_type.

This won't work with an array though -- an array won't provide a typedef of value_type like a vector does.

The usual way to handle this would be to accept a pair of iterators (or pointers, if the underlying "collection" is an array). In this case, you can use std::iterator_traits<T>::value_type to get the value type to which the iterator refers. This will work with raw pointers, so (for example) std::iterator_traits<int *>::value_type will yield int.

If you really have to use a container (and support arrays), you could use std::begin(data) to get an iterator to the beginning of the data, then use std::iterator_traits<T>::value_type on that to get the value_type.

like image 151
Jerry Coffin Avatar answered Apr 12 '23 13:04

Jerry Coffin