模板实现和编译器

Posted

技术标签:

【中文标题】模板实现和编译器【英文标题】:Template implementation & compiler 【发布时间】:2016-12-14 12:09:49 【问题描述】:

我想在 Array.cpp 文件中定义 getRawDataPtr() 函数,我实现如下,我得到了 2 个错误

错误 82 错误 C2653:“数学”:不是类或命名空间名称 错误 84 错误 C2988:无法识别的模板声明/定义
          //file Array.cpp
          template<typename T>
          void * const math::Array<T>::getRawDataPtr
          
          return buffer;
          

    //file Array.h
  #ifndef _ARRAY_
  #define _ARRAY_

  namespace math
 

  //---------------------------------------------------------------------------------------------
  // Do NOT modify this section. For the implementation, see comment below the class declaration
  //---------------------------------------------------------------------------------------------

  /*! The Array class implements a generic two-dimensional array of elements of type T.
  */
   template <typename T>
   class Array
   
   protected:
    //! Flat storage of the elements of the array of type T
    T * buffer;                     

    //! The width of the array (number of columns)
    unsigned int width,             

    //! The height of the array (number of rows)
                 height;            

    public:

    /*! Reports the width (columns) of the array
     *
     * \return the width.
     */
    unsigned int getWidth() const  return width;       

    /*! Reports the height (rows) of the array
     *
     * \return the height.
     */
    unsigned int getHeight() const  return height;     

    /*! Obtains a constant pointer to the internal data.
    *
    *  This is NOT a copy of the internal array data, but rather a pointer
    *  to the internally allocated space.
    */
    void * const getRawDataPtr();

    /*! Returns a reference to the element at the zero-based position (column x, row y).
     *
     * \param x is the zero-based column index of the array.
     * \param y is the zero-based row index of the array.
     * 
     * \return a reference to the element at position (x,y)
     */
     T & operator () (int x, int y);                      

    /*! Returns a constant reference to the element at the zero-based position (column x, row y).
    *
    * \param x is the zero-based column index of the array.
    * \param y is the zero-based row index of the array.
    *
    * \return a reference to the element at position (x,y)
    */
    const T & operator () (int x, int y) const;

    /*! Constructor with array size.
     *
     * No default constructor is provided as it makes no sense. 
     *
     * \param w is the width (columns) of the array
     * \param h is the height (rows) of the array
     */
    Array(unsigned int w, unsigned int h);  

    /*! Copy constructor.
    *
    * No default constructor is provided as it makes no sense.
    *
    * \param source is the array to replicate.
    */
    Array(const Array<T> & source);                      

    /*! Copy assignment operator
    *
    * \param source is the array to replicate.
    */
    Array & operator = (const Array<T> & source); 

    /*! Equality operator.
     *
     *  \param right is the array to compare the current object to.
     *
     *  \return true if the current array and the source have the same dimensions AND 
     *  one by one their elements of type T are the same. 
     */
    bool operator == (const Array<T> & right) const;    

    /*! Changes the internal array data storage size.
    *
    * If the one or both of the given dimensions are smaller, the array should be clipped
    * by discarding the remaining elements in the rows and/or columns outside the margins.
    * If the new dimensions are larger, pad the old elements with default values of type T.
    * If the array is not yet allocated (zero width and height), allocate the internal buffer and
    * set the array size according to the given dimensions.
    *
    * \param new_width is the user-provided width to resize the array to.
    * \param new_height is the user-provided height to resize the array to.
    */
    void resize(unsigned int new_width, unsigned int new_height);   

    /*! Virtual destructor.
     */
    virtual ~Array();                                    

    ;

    //---------------------------------------------------------------------------------------------
    // Do NOT add the member function implementation here. Add all implementations in the Array.hpp 
    // file included below. The two files will be concatenated upon preprocessing.
    //---------------------------------------------------------------------------------------------


     // namespace math

    #include "Array.hpp"

    #endif//------------------------------------------------------------

【问题讨论】:

注释行可以删除.. 以提高可读性。 在声明数学命名空间及其内容之后移动它... @AdrianoRepetti 我应该移动哪个?由于某种原因,它无法识别命名空间! 因为您在声明之前尝试使用该命名空间及其内容。只是编译器不知道(还)。 你不应该有一个“Array.cpp”文件。一直读到最后——“在下面包含的 Array.hpp 文件中添加所有实现。” (并阅读this。) 【参考方案1】:

我想你有一个正确包含的问题(见下文)以及你忘记了getRawDataPtr() 定义中的括号的明显事实。我的意思是:你应该写

      //                parentheses added -----> vv
      void * const math::Array<T>::getRawDataPtr ()
      
      return buffer;
      

关于包含...您的“array.h”包含“array.hpp”但getRawDataPtr() 在“array.cpp”中实现。

您是否将“array.hpp”与“array.cpp”混淆了?

我能说的是下面的代码编译没有错误

namespace math
 
   template <typename T>
      class Array
       
         protected:
            T * buffer;                     

            unsigned int width, height;            

         public:

            unsigned int getWidth() const  return width;       
            unsigned int getHeight() const  return height;     
            void * const getRawDataPtr();
            T & operator () (int x, int y);                      
            const T & operator () (int x, int y) const;
            Array(unsigned int w, unsigned int h);  
            Array(const Array<T> & source);                      
            Array & operator = (const Array<T> & source); 
            bool operator == (const Array<T> & right) const;    
            void resize(unsigned int new_width, unsigned int new_height);   
            virtual ~Array();                                    
       ;
  // namespace math

template<typename T>
void * const math::Array<T>::getRawDataPtr ()
  return buffer; 

int main ()
  

【讨论】:

所以定义应该在Array.hpp中? @madrugadas25845 - 我想在“array.hpp”甚至“array.h”中;它是一个模板类,因此在使用Array&lt;T&gt; 时应该可以看到完整的实现; getRawDataPtr() 它如此简短,我认为可以在Array&lt;T&gt; 的主体中实现,就像getWidth()getHeight()

以上是关于模板实现和编译器的主要内容,如果未能解决你的问题,请参考以下文章

C++ STL 矢量模板如何将其对象存储在 Visual Studio 编译器实现中?

第59课 类模板深度剖析

C++学习(四五三)模板类 模板函数使用注意事项

C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译?

模板与分离编译模式

26.C++- 泛型编程之类模板(详解)