专门用于指针的模板类

时间:2014-10-16 22:02:15

标签: c++ templates specialization

我有一个模板类,如下所示:

template <typename T>
class PacketMember
{
public:
    PacketMember(const std::size_t maxMemberSize, const QString memberName) :
        m_maxMemberSize(maxMemberSize),
        m_memberName(memberName)
    {

    }

    void append(const T data, const std::size_t length)
    {
        if(currentMemberSize() + length <= m_maxMemberSize)
        {
            for(std::size_t i = 0 ; i < length ; ++i) {
                m_data = data;
                m_member.push_back(m_data);
            }
        }
    }

    QString memberName() const
    {
        return m_memberName;
    }

    std::size_t currentMemberSize() const
    {
        return m_member.size();
    }

    std::size_t maxMemberSize() const
    {
        return m_maxMemberSize;
    }

    std::vector<T>* member() const
    {
        return m_member;
    }

    void setMaxMemberSize(const std::size_t newSize) {
        m_maxMemberSize = newSize;
    }

private:
    T m_data;
    std::vector<T> m_member;
    std::size_t m_maxMemberSize;
    QString m_memberName;
};

指针的特化如下:

template <typename T>
class PacketMember<T*>
{
public:
    PacketMember(const std::size_t maxMemberSize, const QString memberName) :
        m_maxMemberSize(maxMemberSize),
        m_memberName(memberName)
    {

    }

    void append(T* data, const std::size_t length)
    {
        if(currentMemberSize() + length <= m_maxMemberSize)
        {
            for(std::size_t i = 0 ; i < length ; ++i) {
                m_data = new T(*data);
                m_member.push_back(m_data);
            }
        }
    }

    QString memberName() const
    {
        return m_memberName;
    }

    std::size_t currentMemberSize() const
    {
        return m_member.size();
    }

    std::size_t maxMemberSize() const
    {
        return m_maxMemberSize;
    }

    std::vector<T*>* member() const
    {
        return &m_member;
    }

private:
    T* m_data;
    std::vector<T*> m_member;
    std::size_t m_maxMemberSize;
    QString m_memberName;
};

当我尝试使用char*将我的班级实例化为PacketMember<char*>时,它会创建一个PacketMember<cha**>的班级。为什么会这样?我应该如何避免指针指向实例化?对不起,如果这是一个基本问题。我对模板的经验非常有限。

修改

我的代码没有任何问题。问题只是QtCreator中的一个错误。我应该删除这个问题吗?请回复评论。谢谢。

1 个答案:

答案 0 :(得分:2)

是什么让你觉得你得到PacketMember<char**>?我看到的一个错误是你的member()函数返回指向成员的指针,但你返回成员本身。对于你原来的问题,这证明没有&#34;双指针&#34;实例:

#include <iostream>

template<typename T>
struct A {
    typedef T type;
};

template<typename T>
struct A<T*> {
    typedef T* pointertype;
};


static_assert(std::is_same<A<int>::type,int>::value,"Non-pointer: Not the same type");
static_assert(std::is_same<A<int*>::pointertype,int*>::value,"Pointer: Not the same type");

int main()
{
    return 0;
}

(我将两个typedef命名为不同,因此您可以看到使用了正确的特化。)

结果:它编译。<​​/ p>

编辑:由于你不使用C ++ 11,这里有一个特殊的技巧(可能有更好的方法)让它在没有static_assert的编译器上工作:

#include <iostream>

template<typename T>
struct A {
    typedef T type;
};

template<typename T>
struct A<T*> {
    typedef T* pointertype;
};


int main()
{
    A<int>::type x = (int)0;
    A<int*>::pointertype y = (int*)0;
    x++;
    y++;
    return 0;
}

如果分配不具有相同的类型(尝试在演员阵容中添加/删除*),则分配将无效。 x++; y++;只是为了使编译器对未使用的变量发出警告。