2016-12-20 11 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; 
} 

しかし、それは強く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<>を使用したコードの効率化に役立ちます。

+0

ありがとう – madrugadas25845

関連する問題