代码之家  ›  专栏  ›  技术社区  ›  Oxymoron

在何处/如何定义模板

  •  3
  • Oxymoron  · 技术社区  · 15 年前

    在C++中定义模板的最佳实践是什么?

    template <class T>
    class A
    {
    private:
        // stuff
    public:
        T DoMagic()
        {
            //method body
        }
    }
    
    Or:
    
    template <class T>
    class A
    {
    private:
        // stuff
    public:
        T DoMagic();
    }
    
    template <class T>
    A::T DoMagic()
    {
        // magic
    }
    

    另一种方式? 关于这个问题,我似乎遇到了一些争议。 那么,选择哪条路呢?

    6 回复  |  直到 13 年前
        1
  •  4
  •   Kornel Kisielewicz    15 年前

    这完全是风格问题。不过,也就是说:

    1. 选择一种方法并坚持下去——要么全部内联,要么全部输出,或者根据某种规则混合使用。
    2. 我个人使用三线规则。如果模板中的方法体长于3行,则将其移到外部。

    没有真正的理由不包括所有内联定义(不管怎样,它们都是从编译器POV内联的),但是,许多人认为保持它们独立更干净,并且允许类定义更可读。

        2
  •  2
  •   rturrado    13 年前

    随着编写的模板越来越大和复杂,请使用越来越高的分离级别。 无论如何将定义与声明分开,性能都是相同的,因此这里主要关注的应该是可读性和可维护性。

    当编写一个只在一个地方使用的简单模板时,在CPP文件中声明并定义它,在CPP文件中您将在其中使用它。如果只有一个代码块需要这个模板,就没有理由强制进行全局重新编译。

    文件.cpp

    template<class Gizmo> bool DoSomethingFancy()
    {
     // ...
    }
    

    对于跨翻译单元使用的小模板实用程序,在H文件中定义并声明它们:

    实用程序.h

    template<class Gizmo> bool DoSomethingUseful() 
    {
      // ...
    }
    

    随着模板变得越来越复杂,能够独立于定义查看声明将变得更加重要。首先,将所有内容分开,但放在同一个文件中:

    效用H

    template<class Type> class Useful
    {
      bool FunctionA();
      bool FunctionB();
    };
    
    template<class Type> bool Useful<Type>::FunctionA()
    {
      // ...
    }
    
    template<class Type> bool Useful<Type>::FunctionB()
    {
      // ...
    }
    

    但最终,即使这样也会变得不明智。当它这样做时,将其分为声明的头文件和定义的inc文件。在头文件的末尾, #include Inc文件:

    效用:H:

    template<class Type> class MoreUseful
        {
          bool FunctionA();
          bool FunctionB();
        };
    
    #include "utility.inc"
    

    公司:

    template<class Type> bool MoreUseful<Type>::FunctionA()
    {
      // ...
    }
    
    template<class Type> bool MoreUseful<Type>::FunctionB()
    {
      // ...
    }
    
        3
  •  1
  •   Thomas Matthews    15 年前

    这是一个宗教(风格)问题。我更喜欢在模板声明之外为具有多个方法或少数方法简单的类定义我的函数。

    在这两种情况下,我的理解是模板声明和方法定义必须在同一翻译单元中。这是因为 template 更像是 模板 ,编译器将给定类型插入 模版 并为给定类型生成代码。

    无论你决定什么,只要始终如一。

        4
  •  1
  •   Manuel    15 年前

    我通常在外部定义所有的方法,但每次我希望C++都有某种“模板块”:

    template <class T>
    struct A
    {
         T foo();
         T bar(T * t);
         T baz(T const & t);
    };
    
    template <class T>  // Made-up syntax
    {
        T A::foo()
        {
            //...
        }
    
        T A::bar(T * t)
        {
            //...        
        }
    
        T A::baz(T const & t)
        {
            //...
        }
    }
    
        5
  •  1
  •   Frederik Slijkerman    15 年前

    如果函数是非平凡的(即多于一行或两行),请考虑分别定义它们。这使得类的接口更容易为类的用户导航、阅读和理解,这些用户很可能不必查看每个方法的实际实现。

        6
  •  0
  •   wallyk    15 年前

    对于像您的示例这样的一次性实例,它没有什么区别。

    当有很多不同的模板时会发生什么?然后,它有助于把相似类型的苹果放在一起,把相似类型的橙子放在一起远离它们。当然,这一切必须尽可能直观地完成。这很大程度上受到了程序员使用代码的文化的影响。