I have a template class method
template<class T>
T pop<T>();
Now I want to do a template specialization as follows,
template<class T>
std::vector<T> pop<T>();
I can do the following no problem,
template<>
std::vector<int> classname::pop<std::vector<int>>();
But I still need to leave the type as a template parameter. How do I accomplish this?
It is possible in C++ to get a special behavior for a particular data type. This is called template specialization. Template allows us to define generic classes and generic functions and thus provide support for generic programming.
Vectors, or std::vector , are a template class in the STL (Standard Template Library). But what does that mean? They are a more flexible, refined, and efficient replacement for arrays, which are used in the C programming language (and on which the C++ language is based).
C++ provides a vector template class, as part of Standard Template Library (STL). It is defined in header <vector> , belonging to the namespace std . (In computing, a vector refers to an array-like structure that holds a set of direct-access elements of the same kinds, instead of mathematical n-component vector.)
A template is a C++ programming feature that permits function and class operations with generic types, which allows functionality with different data types without rewriting entire code blocks for each type.
Off the top of my head, I usually get around it by using a one-member struct:
template <typename T>
struct pop_impl {
static T pop(classname& x); // normal function
};
template <typename T>
struct pop_impl<std::vector<T>> {
static std::vector<T> pop(classname& x); // specialized for std::vector<T>
};
template <typename T>
T classname::pop() { return pop_impl<T>::pop(*this); }
This answer was originally provided by Austin Salgat in the body of the question Template Specialization for T -> std::vector, (posted under the CC BY-SA 3.0 license), and has been moved here as an answer in order to adhere to the site's Q&A format.
Thanks to Piotr I ended up using tag dispatching. Below is the code for what I ended up doing,
// The public method that is accessed by class.push<std::vector<int>>(12); template<class T> void push(T data) { push(tag<T>(), data); } // The private method that calls the actual vector push for vector types template<class T> void push(tag<std::vector<T>>, std::vector<T> const& data_vector) { push_vector(data_vector); } // The actual implementation template<class T> void push_vector(std::vector<T> const& data_vector) { // Actual implementation in here }
A possible solution is a non-member function implemented like this
template <class T>
struct classname_pop
{
static T pop(classname &obj) { return obj.pop() ;}
}
template <class T>
struct classname_pop<std::vector<T>>
{
static std::vector<T> pop(classname &obj) {obj.specialized_pop() ;}
}
template <class T>
T classname_pop(classname &obj)
{
return classname_pop_t<T>::pop() ;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With