2014-10-16 3 views
2

У меня есть класс шаблона следующим образом:, специализирующийся класс шаблона для указателей

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**>. почему это происходит? как я должен избегать создания указателя на указатель? Извините, если это основной вопрос. У меня очень ограниченный опыт работы с шаблонами.

EDIT:

Там не было ничего плохого с моим кодом. Проблема была всего лишь ошибкой в ​​QtCreator. Должен ли я удалить этот вопрос? ответьте в комментариях. Спасибо.

+0

Можете ли вы опубликовать свою реализацию? – Samer

+0

@Samer реализация чего? если вы имеете в виду функции класса, то это шаблон, который находится в файле заголовка. – Barracuda

+0

как вы создаете экземпляр объекта класса? – Samer

ответ

2

Почему вы думаете, что получаете PacketMember<char**>? Одна ошибка, которую я вижу, заключается в том, что ваша функция member() возвращает указатель на элемент, но вы возвращаете сам элемент. Для вашего первоначального вопроса, это доказывает, что нет «двойного указателя» конкретизации: (. Я назвал эти два определения типов по-разному, так что вы можете видеть, используются правильная специализация)

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

Результат: Компилируется ,

EDIT: Поскольку вы не используете 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++; просто отключает предупреждение компилятора о неиспользуемых переменных.

+0

Я не использую компилятор, совместимый с C++ 11. не могли бы вы отредактировать ответ, чтобы его можно было компилировать с помощью старых компиляторов? – Barracuda

+0

@MoKi '#include ... assert (typeid ((A :: type)) == typeid (int)); assert ((typeid (A :: type)) == typeid (int *)) '. – 0x499602D2

+0

О, мне очень жаль, я думал, что у меня проблема, потому что моя IDE (QtCreator) показывала мне это не компилятор. когда я вводил имя функции, он показывал мне, как будто я пытаюсь получить доступ к экземпляру моего шаблона с типом 'char **' и из-за неполного и не компилируемого кода, и мой недостаток опыта с шаблоном я думал Я делаю что-то не так. Теперь я проверил свой код и не создавал экземпляр с типом 'char **'. Вероятно, это ошибка в QtCreator. я должен удалить этот вопрос? – Barracuda

Смежные вопросы