在类的内部和外部定义的模板类的成员函数之间的差异

时间:2010-01-20 17:49:25

标签: c++ class templates inline

为类声明中的模板类定义成员函数与外部之间是否存在差异?

内部定义:

template <typename T>
class A
{
public:
    void method()
    {
        //...
    }
};

在外面定义:

template <typename T>
class B
{
public:
    void method();
};

template <typename T>
void B<T>::method()
{
    //...
}

对于非模板类,这是内联和非内联方法之间的区别。模板类也是如此吗?

我的大多数同事的默认设置是在类中提供定义,但我总是更喜欢类外的定义。我的偏好是否合理?

编辑:请假设所有上述代码都在该类的头文件中提供。

3 个答案:

答案 0 :(得分:2)

是的,模板类完全相同。

模板类的方法定义通常首选内联的原因是,对于模板,在实例化模板时,整个定义必须是可见的。

因此,如果将函数定义放在某个单独的.cpp文件中,则会出现链接器错误。 唯一的通用解决方案是通过在类内部或在inline关键字外部定义函数来使函数内联。但在任何一种情况下,它必须在调用函数的任何地方都可见,这意味着它通常必须与类定义在同一个头中。

答案 1 :(得分:1)

除了必须输入更多内容之外没有区别。这包括template位,inline,并且在引用类时必须使用更多“精心”的名称。例如

template <typename T> class A { 
  A method(A a) { 
    // whatever
  } 
}; 

template <typename T> inline A<T> A<T>::method(A a) { 
  // whatever
} 

请注意,当在内部定义方法时,您可以在引用<T>时省略模板参数列表A<T>,并使用A。在外部定义时,必须在返回类型和方法名称中使用“完整”名称(但不在参数列表中)。

答案 2 :(得分:0)

我知道这一点......我认为它必须是一些对你有帮助的东西吗?

defining a member function outside of its template

提供模板类的成员函数的定义是不正确的:

 // This might be in a header file:
 template <typename T>
 class xyz {
    void foo();
  };

// ...

 // This might be later on in the header file:
  void xyz<T>::foo() {
// generic definition of foo()
   }

出于某些原因,这是错误的。这就是:

      void xyz<class T>::foo() {
         // generic definition of foo()
      }

正确的定义需要template关键字和声明类模板定义的模板参数。所以这给了:

       template <typename T>
          void xyz<T>::foo() {
           // generic definition of foo()
                 }

请注意,还有其他类型的模板指令,例如成员模板等,每个都采用自己的形式。重要的是要知道你有哪些,所以你知道如何写每种口味。这是特别的,因为一些编译器的错误消息可能不清楚是什么问题。当然,要获得一本好的和最新的书。

如果模板中有嵌套的成员模板:

    template <typename T>
      struct xyz {
      // ...
      template <typename U>
       struct abc;
        // ...
       };

如何在xyz之外定义abc?这不起作用:

     template <typename U>
    struct xyz::abc<U> { // Nope
      // ...
  };

也不是这样:

 template <typename T, typename U>
 struct xyz<T>::abc<U> { // Nope
// ...
 };

你必须这样做:

     template <typename T>
       template <typename U>
           struct xyz<T>::abc {
            // ...
           };

请注意,...abc不是...abc<U>,因为abc是“主要”模板。 IOWs,这不好:

//这里不允许:        模板模板struct xyz :: abc {};