模板中的错误"需要模板参数列表"

时间:2016-12-20 11:24:35

标签: c++ list templates arguments operators

错误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 个答案:

答案 0 :(得分:0)

我建议从稍微简单的代码开始学习C ++。您的代码中存在多个错误和问题。

首先语法Array类模板,但不是typename,因此不能用作返回类型。您必须提供完全限定的名称,即

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

但是,强烈建议避免使用newdelete 运算符。以异常安全和线程安全的方式有效地使用它们并且没有内存泄漏是(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<>更高效地制作代码。