【问题标题】:error in templates "requires template argument list"模板中的错误“需要模板参数列表”
【发布时间】:2017-05-05 14:31:00
【问题描述】:

error 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

【问题讨论】:

  • 请发minimal reproducible example。上下文很重要。
  • 我怀疑返回值应该是Array&lt;T&gt;&amp;
  • Array &amp; Array &lt;T&gt;::operator =... first Array 应该是什么?
  • @Someprogrammerdude 我无法更改声明,只能更改 Array.hpp 文件中的定义。
  • @Someprogrammerdude 数组是头文件中的一个类

标签: c++ list templates arguments operators


【解决方案1】:

我建议从更简单的代码开始学习 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&amp;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&lt;T&gt; 数据成员中,或者您可以拥有std::unique_ptr&lt;T[]&gt;。在后一种情况下,您可以

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&lt;&gt; 的代码效率。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    相关资源
    最近更新 更多