c++ - 不分离模板类的函数声明和定义是一个好习惯吗?

标签 c++ c++11 templates compiler-errors

通常在非模板类中,我们将函数声明和定义分离到单独的文件中(.h 和 .cpp)

[1] 但是上面的做法对于模板类来说似乎不太有效。是否建议将实现编写在单独的文件中,然后将其包含在 .h 文件的底部?

[2] 对于模板类,通常建议使用以下哪种方案?
[a] 声明和定义同时进行或
[b]同一文件中的单独声明和定义

考虑到如果我们选择的话我们必须处理复杂的语法[b]

例如。 [一]

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  ***/

最佳答案

某些函数,如“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 的模板 friend .

但即使在那里,你也可以这样做:

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"
};

如果你真的想拆分实现和接口(interface)。

将实现和接口(interface)分离为单独的 .h 不存在技术障碍和.inc文件,将定义内联放置在模板声明中,或将定义放置在 .h 的末尾文件。使用多个文件对编译时间的影响很小(因为通常必须在 #include 上触及文件系统或相同的缓存),但与其他因素相比通常并不大。

关于c++ - 不分离模板类的函数声明和定义是一个好习惯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54200421/

相关文章:

c++ - 找不到默认构造函数来初始化 cpp 中的成员

c++ - C++11 thread_local 变量可以从父线程继承它的初始值吗?

c++ - 是否可以推迟仿函数的生成?

c++ - 包含 std::threads 的元素 vector

c++ - 模板和矩阵转换

c++ - boost::scoped_lock 似乎没有锁定 std::cout

c++ - Socket C++ 程序编译成功在运行时崩溃

c++ - 使用指向成员函数的指针与使用开关的成本是多少?

c++ - 如何测试类 B 是否派生自类的模板族

c++ - 类模板中不可能有默认的 lambda