我在这个主题上搜索了很多。我遇到了三种方法。假设我们有3个文件,main.cpp,声明头文件和definiton cpp文件。 第一种方法建议在cpp文件中创建临时对象。 第二种方法建议在主文件中包含cpp和头文件。 第三种方法建议在头文件中包含cpp文件。
现在的问题是:哪一个是最好的方法?通过说得最好,我的意思是兼具良好的性能和良好的代码样式。 还有其他更好的方法吗?
答案 0 :(得分:1)
应始终在类体内定义模板。这是最受欢迎的解决方案,因为它简单明了,可以避免大量不必要的打字。
考虑以下课程:
template <CharEncoding Encoding>
class UnicodeConverter
{
protected:
template <typename Input_char_type, typename Output_char_type>
class InternalHelper
{
public:
void function_a()
{
//do something
}
};
//...
};
现在想象一下,如果你想要一个单独的定义文件,你需要写什么:
template <CharEncoding Encoding>
template <typename Input_char_type, typename Output_char_type>
void UnicodeConverter<Encoding>::InternalHelper<Input_char_type, Output_char_type>::function_a()
{
//do something
}
这绝对不是很好也不可读,你不同意吗?
在某些情况下,定义必须分开(例如,两个模板,彼此依赖),但在大多数情况下:避免它!
将实施放在单独的.cpp
文件中的规则通常不适用于模板。 C ++标准库也主要是基于头的,因为它广泛使用模板来处理所有事情。
另外,请注意,我的示例代码是一个真实的示例,取自真实的应用程序(稍加修改)。并且想象一下,这不是我在这个项目中最复杂的模板。
答案 1 :(得分:1)
第一种方法建议在cpp文件中创建一个临时对象。
第二种方法建议在主文件中包含cpp和头文件。
大多数编译器不支持以这种方式拆分模板代码。它需要使用外部模板定义,但尚未得到广泛支持。大多数编译器都需要在同一个翻译单元中声明和定义模板。这带给我们第三个选择...
第三种方法建议在头文件中包含cpp文件。
这是大多数人采用的方法,如果他们甚至根据定义将模板声明分开(参见下面的第4个选项)。但是,通常使用.icc
文件扩展名而不是.cpp
命名定义文件,以使此区别更清晰。例如:
myfile.h:
template<typename T>
class TMyClass
{
public:
void doSomething(T value);
};
#include "myfile.icc"
myfile.icc:
template<typename T> void TMyClass<T>::doSomething(T value)
{
//...
}
这将我们带到第4个选项 - 根本不拆分代码,而是实现内联。这是编写模板的更常用方法。例如:
myfile.h:
template<typename T>
class TMyClass
{
public:
void doSomething(T value)
{
//...
}
};