Template Specialization for T -> std::vector

后端 未结 4 822
情歌与酒
情歌与酒 2021-01-12 15:54

I have a template class method

template
T pop();

Now I want to do a template specialization as follows,



        
相关标签:
4条回答
  • 2021-01-12 15:59

    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); }
    
    0 讨论(0)
  • 2021-01-12 16:03

    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() ;
    }
    
    0 讨论(0)
  • 2021-01-12 16:12

    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
    }
    
    0 讨论(0)
  • 2021-01-12 16:23

    You need a temporary proxy to dispatch to different results:

    Example:

    #include <algorithm>
    #include <iostream>
    #include <vector>
    
    class Stack
    {
        private:
        std::vector<int> m_data;
    
        class Pop {
            friend class Stack;
    
            public:
            Stack& stack;
    
            Pop(Stack& stack)
            :   stack(stack)
            {}
    
            private:
            Pop(const Pop&) = default;
            Pop& operator = (const Pop&) = default;
    
            public:
            operator int () {
                std::vector<int>& data = stack.m_data;
                int result = -1;
                if( ! data.empty()) {
                    result = data.front();
                    data.erase(data.begin());
                }
                return result;
            }
    
            operator std::vector<int> () {
                std::vector<int>& data = stack.m_data;
                std::size_t size = std::min(data.size(), std::size_t(3));
                std::vector<int> result(data.begin(), data.begin() + size);
                data.erase(data.begin(), data.begin() + size);
                return result;
            }
        };
    
        public:
        Stack()
        :   m_data( {0, 1, 2, 3, 4, 5, 6, 7, 8} )
        {}
    
        const std::vector<int>& data() const { return m_data; }
        Pop pop() { return Pop(*this); }
    };
    
    int main()
    {
        Stack stack;
        int i = stack.pop();
        std::vector<int> v = stack.pop();
        std::cout << "i = " << i << '\n';
        std::cout << "v = {";
        for(auto i : v)
            std::cout << i;
        std::cout << "}\n";
    }
    

    Disclaimer: I consider the code totally useless (It might become useful if there is a pop() just returning a single value and a pop(std::size_t) converting to different containers, where the destructor of Pop is doing the erase).

    0 讨论(0)
提交回复
热议问题