在命名空间中定义模板类成员函数?

时间:2017-06-30 02:25:16

标签: c++

我环顾四周,试图找到答案。是否可以在cpp文件中的命名空间中定义模板类的成员函数?我尝试这样做时出错了。

以下是我要编译的两个文件。

ArrayList.hpp

     template<typename T>
     class ArrayList{
          ArrayList();
          ~ArrayList();
     }

ArrayList.cpp

    #include "ArrayList.hpp"

    namespace{

        template<typename T>
        ArrayList<T>::ArrayList(){

         /* function body goes here */

        }

        ArrayList<T>::~ArrayList(){

         /* function body goes here */

        }

编译器错误

 error: cannot define or
  redeclare 'ArrayList<T>' here because namespace '' does not enclose
  namespace 'ArrayList'
  ArrayList<T>::ArrayList()

3 个答案:

答案 0 :(得分:3)

您需要在定义其成员函数的同一名称空间中声明您的类。

你在析构函数之前错过了template<typename T>

namespace ANamespace
{

    template<typename T>
    class ArrayList
    {
        ArrayList();
        ~ArrayList();
    };

    template<typename T>
    ArrayList<T>::ArrayList()
    {

        /* function body goes here */

    }

    template<typename T>
    ArrayList<T>::~ArrayList()
    {

        /* function body goes here */

    }
}

答案 1 :(得分:2)

  

是否可以在cpp文件中的命名空间中定义模板类的成员函数?

不,那是不可能的。与任何其他类声明一样,成员函数声明及其定义必须出现在同一名称空间中。

在您的示例中使用的未命名的命名空间也只能在该特定的翻译单元中看到。

您通常无法将模板定义放在单独的翻译单元中(除非您有特定的专业化案例)。请阅读更多相关信息:

Why can templates only be implemented in the header file?

如何解决?

只需将所有内容移到头文件中,然后删除未命名的命名空间,如下所示:

ArrayList.hpp

 template<typename T>
 class ArrayList{
      ArrayList();
      ~ArrayList();
 }; // Semicolon at end of class declaration is essential

 template<typename T>
 ArrayList<T>::ArrayList(){
     /* function body goes here */
 }

 template<typename T> // <<<<< Repeat for evey function definition
 ArrayList<T>::~ArrayList(){
    /* function body goes here */
 }

如果你真的想拥有一个命名空间,只需提供一个命名空间并将上面的所有内容(仍在标题中)包含在内:

 namespace MyUtilities {
     template<typename T>
     class ArrayList{
     public: // <<<<<< Allow access to these functions
          ArrayList();
          ~ArrayList();
     };

     template<typename T>
     ArrayList<T>::ArrayList(){
          /* function body goes here */
     }

     template<typename T>
     ArrayList<T>::~ArrayList(){
         /* function body goes here */
     }
 }

请参阅完整的工作示例here

同样要使这些内容可用,请使用上面显示的public关键字。

答案 2 :(得分:1)

首先,您无法在.cpp文件中定义模板类的方法。您需要在头文件本身(或在另一个文件中定义模板类方法,然后通过头文件本身中的预处理器包含它来导入)有关更多信息,请参阅Why can templates only be implemented in the header file?

匿名名称空间namespace {用于定义具有内部链接的内容,即类似于static对实现文件中定义的函数的影响。阅读本文以获取更多信息Why are unnamed namespaces used and what are their benefits?

但在您的情况下,您希望将类方法定义为外部可见,因为您已在头文件中公开声明它们。因此,您可能不希望将这些定义放在匿名命名空间中。

如果您的头文件中包含了一个名称空间,例如namespace array_list,那么您应该只在头文件本身的中定义您的类方法,因为它&# 39; sa模板类,需要在任何地方都可见。