2016-12-20 4 views
-1

ошибка C2955: 'math :: Array': использование шаблона шаблона требует списка аргументов шаблона, есть ли у кого-нибудь идеи, почему я беру ошибку?ошибка в шаблонах «требуется список аргументов шаблона»

Array.h

#ifndef _ARRAY_ 
#define _ARRAY_ 
namespace math 
{ 
template <typename T> 
class Array 
{ 
protected: 
    //! Flat storage of the elements of the array of type T 
    T * buffer;      
    unsigned int width, height;   

public: 
Array & operator = (const Array<T> & source); 
    }; 

} // namespace math 

#include "Array.hpp" 
#endif 

Array.hpp

#ifndef _ARRAY_IMPLEMENTATION_ 
    #define _ARRAY_IMPLEMENTATION_ 

namespace math 
{ 
    template<typename T> 
    Array & Array <T>::operator = (const Array<T>& source) 
    { 
    int size = 3 * getWidth() * getHeight(); 
    Array<T> buffer = new Vec3<T>[size]; 
    return *buffer; 
    } 
} // namespace math 

#endif 
+1

Опубликовать [mcve], пожалуйста. Контекст важен. – Angew

+4

Я подозреваю, что возвращаемое значение должно быть 'Array &' –

+0

'Array & Array :: operator =' ... Что такое * первый * 'Array', который должен быть? –

ответ

0

Я рекомендую начать с несколько более простым кодом для изучения C++. В вашем коде есть несколько ошибок и проблем.

Первый, синтаксис. Array является шаблоном класса , но не является именем типа и, следовательно, не может использоваться как возвращаемый тип. Вы должны дать полное имя, т.е.

template<typename T> 
Array<T>& Array<T>::operator = (const Array<T>& source); 

Однако в определении шаблона, имя шаблона можно использовать вместо полного имени, таким образом, вы можете также сказать (заметить разницу)

template<typename T> 
Array<T>& Array<T>::operator = (const Array& source); 

Второй, то логика. У многих классов есть назначение operator=(type const&other). Идея состоит в том, что значение *this изменяется на значение other. Возвращаемое значение должно быть *this. Таким образом, в вашем случае (docu for std::memcpy)

template<typename T> 
Array<T>& Array<T>::operator = (const Array& other) 
{ 
    const auto alloc = other.width * other.height; 
    if(alloc != width*height) {       // need to re-allocate? 
    if(buffer) delete[] buffer;      // delete old memory 
    buffer = alloc? new T[alloc] : nullptr;   // allocate new memory 
    } 
    width = other.width; 
    height= other.height; 
    if(alloc) 
    std::memcpy(buffer,other.buffer,sizeof(T)*alloc); // copy data 
    return*this; 
} 

Тем не менее, настоятельно рекомендуется избегать использования new и delete операторов. Их эффективное использование в безопасном и безопасном потоке и без утечек памяти (1) нетривиально и (2) лучшие альтернативы предоставляются библиотекой C++. Ваш код, например, утечки памяти и не может инициализировать buffer до nullptr в случае строительства по умолчанию (возможно, вызывает ошибку сегментации).

Вы можете сохранить данные в элементе данных std::vector<T>, или у вас может быть std::unique_ptr<T[]>. В последнем случае вы можете

template <typename T> 
class Array 
{ 
protected: 
    size_t width=0, height=0;    // provide default values; 
    std::unique_ptr<T[]> buffer; 
public: 
    Array() = default;      // default constructor: empty 
    Array(Array&&) = default;    // move constructor 
    Array&operator=(Array&&) = default; // move assignment 
    Array(Array const&other)    // copy constructor 
    : width(other.width) 
    , height(other.height) 
    , buffer(other.buffer? new T[width*height]:nullptr) 
    { 
    if(buffer) 
     std::memcopy(buffer.get(),other.buffer.get(),width*height*sizeof(T)); 
    } 
    Array&operator=(Array const&other)  // copy assignment 
    { 
    const auto alloc = other.width * other.height; 
    if(alloc != width*height) 
     buffer.reset(alloc? new T[alloc]:nullptr); 
    width = other.width; 
    height= other.height; 
    if(alloc) 
     std::memcopy(buffer.get(),other.buffer.get(),alloc*sizeof(T)); 
    return*this; 
    } 
    Array(size_t w, size_t h)  // construct with given width & height 
    : width(w), height(h), buffer(w*h? new T[w*h]:nullptr) 
    {}       // leave data uninitialised 
    // you don't need to explicitly declare a destructor 
}; 

Обратите внимание на наличие конструктора перемещения и назначения. Они могут помочь сделать код с использованием Array<> более эффективным.

+0

большое спасибо – madrugadas25845

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