T的模板专业化 - >的std ::矢量<T>

时间:2015-06-03 17:29:33

标签: c++ templates

我有一个模板类方法

framgentId, eventType

现在我想按照以下方式进行模板专业化,

template<class T>
T pop<T>();

我可以做到以下没问题,

template<class T>
std::vector<T> pop<T>();

但是我仍然需要将类型保留为模板参数。我该如何做到这一点?

编辑:感谢Piotr,我最终使用了标签调度。下面是我最终做的代码,

template<>
std::vector<int> classname::pop<std::vector<int>>();

4 个答案:

答案 0 :(得分:5)

在我的头顶,我通常使用一个成员结构绕过它:

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); }

答案 1 :(得分:1)

可能的解决方案是像这样实现的非成员函数

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() ;
}

答案 2 :(得分:1)

此答案最初由Austin Salgat在问题Template Specialization for T -> std::vector的正文中提供(根据CC BY-SA 3.0许可证发布),并已移至此处作为答案,以便坚持网站的问答格式。


多亏了Piotr,我最终使用了标签分派。下面是代码 我最终要做的事,

// 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
}

答案 3 :(得分:0)

您需要一个临时代理才能分派到不同的结果:

示例:

#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";
}

免责声明:我认为代码完全无用(如果有一个pop()只返回一个值而pop(std :: size_t)转换为不同的容器,它可能会变得有用Pop的析构函数正在擦除。)