Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template Specialization for T -> std::vector<T>

Tags:

c++

templates

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?

like image 591
Austin Salgat Avatar asked Jun 03 '15 17:06

Austin Salgat


People also ask

Is specialization of template C++?

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.

Is STD A vector template?

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).

Is Vector a template in C++?

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.)

What does template <> mean in C++?

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.


3 Answers

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); }
like image 65
kirbyfan64sos Avatar answered Nov 09 '22 13:11

kirbyfan64sos


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
}
like image 32
4 revs Avatar answered Nov 09 '22 12:11

4 revs


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() ;
}
like image 1
marom Avatar answered Nov 09 '22 11:11

marom