在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
}
另一种方式? 我似乎偶然发现了一些关于这个问题的争议。 所以;选择什么途径?
答案 0 :(得分:4)
这完全是一种风格问题。然而,那说:
没有真正的理由不将内联所有定义包含在内(无论如何它们都是编译器POV内联的),然而,许多人认为保持它们分离更加干净,并且允许类定义更具可读性。
答案 1 :(得分:2)
随着您编写的模板变得越来越大,越来越复杂,使用越来越高的分离级别。 无论您如何将定义与声明分开,性能都是相同的,因此您的主要关注点应该是可读性和可维护性。
在编写仅在一个地方使用的简单模板时,请使用CPP文件中的声明内联声明并定义它,您将要在其中使用它。如果只有一个代码块需要此模板,则没有理由强制进行全局重新编译。
template<class Gizmo> bool DoSomethingFancy()
{
// ...
}
对于翻译单元中使用的小模板实用程序,请在H文件中一起定义和声明它们:
template<class Gizmo> bool DoSomethingUseful()
{
// ...
}
随着模板变得越来越复杂,能够与定义分开查看声明将变得更加重要。首先,将所有内容分开,但保存在同一个文件中:
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文件:
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()
{
// ...
}
答案 2 :(得分:1)
这是宗教(风格)问题。我更喜欢在模板声明之外为具有多个方法的类定义我的函数,或者几个方法很简单。
在任何一种情况下,我的理解是模板声明和方法定义必须在同一个翻译单元中。这是因为template
更像是模板,编译器将给定类型插入模板并为给定类型生成代码。
无论你决定什么,都要保持一致。
答案 3 :(得分:1)
我通常在外面定义所有方法,但每次我希望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)
{
//...
}
}
答案 4 :(得分:1)
如果函数是非平凡的(即多于一行或两行),请考虑单独定义它们。这使得类的接口更易于为类的用户导航,阅读和理解,他们很可能不必查看每个方法的实际实现。
答案 5 :(得分:0)
对于像你的例子这样的一次性实例,它没什么区别。
当有很多模板有很多变化时会发生什么?然后它有助于将类似类型的苹果放在一起,并将类似类型的橙子放在一起。当然,这必须尽可能直观地完成。这很大程度上受到使用代码的程序员文化的影响。