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

时间:2022-08-21 22:53:18

Is there a difference between defining member functions for a template class inside the class declaration versus outside?

在类声明中为模板类定义成员函数与在类声明之外定义成员函数之间有区别吗?

Defined inside:

内部定义的:

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

Defined outside:

外的定义:

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

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

For non-template classes, this is the difference between inlined and non-inlined methods. Is this also true for template classes?

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

The default for most of my colleagues is to provide definitions inside the class, but I've always preferred definitions outside the class. Is my preference justified?

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

Edit: Please assume all the above code is provided in the header file for the class.

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

3 个解决方案

#1


2  

Yes, the exact same is true for template classes.

是的,模板类也是如此。

The reason why method definitions for template classes are usually preferred to be inline is that with templates, the entire definition must be visible when the template is instantiated.

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

So if you put the function definition in some separate .cpp file, you'll get a linker error. The only general solution is to make the function inline, either by defining it inside the class or outside with the inline keyword. but in either cases, it must be visible anywhere the function is called, which means it must typically be in the same header as the class definition.

如果你把函数定义放在一个单独的。cpp文件中,你会得到一个链接器错误。唯一的通用解决方案是将函数内联,要么在类内部定义它,要么在类外部使用inline关键字。但在这两种情况下,它必须在调用函数的任何地方都是可见的,这意味着它通常必须与类定义位于同一个头中。

#2


1  

There's no difference, aside from having to type more. That includes the template bit, the inline and having to use more "elaborate" names when referring to the class. For example

除了必须输入更多信息之外,没有什么区别。这包括模板位、内联和在引用类时必须使用更“复杂”的名称。例如

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

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

Note that when the method is defined inside you can always omit the template parameter list <T> when referring to A<T> and just use A. When defining it outside, you have to use the "full" name in the return type and in the name of the method (but not in the parameter list).

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

#3


0  

I know this..I think it must be some what help full to u?

我知道这. .我想这一定对你有什么帮助?

defining a member function outside of its template

It is not ok to provide the definition of a member function of a template class like this:

不可以提供模板类的成员函数的定义如下:

 // 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()
   }

This is wrong for a few reasons. So is this:

这是错误的,有几个原因。所以是这样的:

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

The proper definition needs the template keyword and the same template arguments that the class template's definition was declared with. So that gives:

适当的定义需要模板关键字和与类模板定义相同的模板参数。所以给:

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

Note that there are other types of template directives, such as member templates, etc., and each takes on their own form. What's important is to know which you have so you know how to write each flavor. This is so especially since the error messages of some compilers may not be clear as to what is wrong. And of course, get a good and up to date book.

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

If you have a nested member template within a template:

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

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

How do you define abc outside of xyz? This does not work:

在xyz之外如何定义abc ?这并不工作:

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

nor does this:

也没有这样的:

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

You would have to do this:

你必须这样做:

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

Note that it's ...abc not ...abc<U> because abc is a "primary" template. IOWs, this is not good:

请注意,这是……美国广播公司(abc)不是……abc,因为abc是一个“主”模板。IOWs,这不好:

// not allowed here: template template struct xyz::abc { };

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

#1


2  

Yes, the exact same is true for template classes.

是的,模板类也是如此。

The reason why method definitions for template classes are usually preferred to be inline is that with templates, the entire definition must be visible when the template is instantiated.

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

So if you put the function definition in some separate .cpp file, you'll get a linker error. The only general solution is to make the function inline, either by defining it inside the class or outside with the inline keyword. but in either cases, it must be visible anywhere the function is called, which means it must typically be in the same header as the class definition.

如果你把函数定义放在一个单独的。cpp文件中,你会得到一个链接器错误。唯一的通用解决方案是将函数内联,要么在类内部定义它,要么在类外部使用inline关键字。但在这两种情况下,它必须在调用函数的任何地方都是可见的,这意味着它通常必须与类定义位于同一个头中。

#2


1  

There's no difference, aside from having to type more. That includes the template bit, the inline and having to use more "elaborate" names when referring to the class. For example

除了必须输入更多信息之外,没有什么区别。这包括模板位、内联和在引用类时必须使用更“复杂”的名称。例如

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

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

Note that when the method is defined inside you can always omit the template parameter list <T> when referring to A<T> and just use A. When defining it outside, you have to use the "full" name in the return type and in the name of the method (but not in the parameter list).

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

#3


0  

I know this..I think it must be some what help full to u?

我知道这. .我想这一定对你有什么帮助?

defining a member function outside of its template

It is not ok to provide the definition of a member function of a template class like this:

不可以提供模板类的成员函数的定义如下:

 // 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()
   }

This is wrong for a few reasons. So is this:

这是错误的,有几个原因。所以是这样的:

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

The proper definition needs the template keyword and the same template arguments that the class template's definition was declared with. So that gives:

适当的定义需要模板关键字和与类模板定义相同的模板参数。所以给:

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

Note that there are other types of template directives, such as member templates, etc., and each takes on their own form. What's important is to know which you have so you know how to write each flavor. This is so especially since the error messages of some compilers may not be clear as to what is wrong. And of course, get a good and up to date book.

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

If you have a nested member template within a template:

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

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

How do you define abc outside of xyz? This does not work:

在xyz之外如何定义abc ?这并不工作:

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

nor does this:

也没有这样的:

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

You would have to do this:

你必须这样做:

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

Note that it's ...abc not ...abc<U> because abc is a "primary" template. IOWs, this is not good:

请注意,这是……美国广播公司(abc)不是……abc,因为abc是一个“主”模板。IOWs,这不好:

// not allowed here: template template struct xyz::abc { };

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