通常在非模板化类中,我们将函数声明和定义分为单独的文件(.h和.cpp)
[1]但是上述实践似乎不适用于模板化类。是否建议在单独的文件中编写实现,然后将其包含在.h文件的底部?
[2]对于模板类,通常建议使用以下哪种方案?
[a]一次或全部声明和定义
[b]在同一文件中分隔的声明和定义
鉴于我们选择[b]时必须注意的复杂语法
例如。 [a]
template <typename T>
class unique_ptr final {
private:
T* ptr_;
public:
unique_ptr (T* ptr = nullptr) noexcept {
: ptr_{ ptr } {
}
friend bool operator == (const unique_ptr& lhs, const unique_ptr& rhs) {
return lhs.get() == rhs.get();
}
};
[b]
template <typename T>
class unique_ptr final {
private:
T* ptr_;
public:
unique_ptr (T* ptr = nullptr) noexcept;
friend bool operator == (const unique_ptr& lhs, const unique_ptr& rhs);
/*** implementations inside the class after all declarations (I am not sure if this makes the code code any easier to understand) ***/
};
/**** Implementations outside the class ***/
/*** Convoluted things needed to make friend functions work ***/
/** like mentioned in : https://stackoverflow.com/questions/3989678/c-template-friend-operator-overloading ***/
答案 0 :(得分:2)
某些函数,例如“ Koenig运算符”,不能在类本身之外定义:
friend bool operator == (const unique_ptr& lhs, const unique_ptr& rhs) {
return lhs.get() == rhs.get();
}
这是unique_ptr<T>
的非模板朋友,为unique_ptr
的每个模板实例生成。 C ++中没有语法允许在unique_ptr
之外定义其主体。 (您可以创建在外部定义的模板朋友,但不能创建其参数取决于模板类的模板参数的非模板朋友)。
我们可以通过以下方法解决此问题:
friend bool operator == (const unique_ptr& lhs, const unique_ptr& rhs) {
return equal(lhs, rhs);
}
,然后将equal
定义为unique_ptr
的模板朋友。
但是即使在那儿,您也可以这样做:
template <typename T>
class unique_ptr final {
private:
T* ptr_;
public:
unique_ptr (T* ptr = nullptr) noexcept {
: ptr_{ ptr } {
}
friend bool operator == (const unique_ptr& lhs, const unique_ptr& rhs)
#include "unique_ptr_t_operator_equal_function_body.inc"
};
如果您真的想拆分实现和接口。
将实现和接口分为单独的.h
和.inc
文件,将定义内联到模板声明中或将定义放在.h
的末尾没有技术障碍。文件。使用多个文件对编译时间影响很小(因为通常必须在#include
上访问文件系统或相同的缓存),但是与其他因素相比通常并不大。