我想知道这个模板业务.
在C和C++中,将声明放在源文件中的头文件和定义中是很常见的,并将两者完全分开.然而,在模板方面,这似乎不可能(以任何好的方式),而且众所周知,模板是一个很好的工具.
此外,Boost主要是标题,所以这是一个真正的问题.在C++中分离标题和源代码仍然是一个好主意,还是我不应该非常依赖模板?
在我正在开发的项目中,我目前正在实现一个模板化的算法.我在组织我的函数声明和定义时遇到了一些问题,因为涉及模板(我在这里问了一个关于如何处理非模板化函数的问题" 与模板化函数一起分组").然而,这使我对这种文件的一般正确组织感到疑惑.
我想将所有定义与所有声明分开(仅出于可读性的目的,即使我必须将模板化定义包含在声明中).
我得到的答案建议组织如下:
algo.h所有函数声明的声明文件algo.tpp将被包含在algo.h(模板需要在编译时声明)algo.cpp不包含在任何地方.如果所有定义的函数都应该对最终用户可见(即所有声明都在algo.h文件中),这很有效.但是,有时我喜欢将我的大功能分解为更小的功能,但我希望最终用户只能访问"大功能",而不能访问他们的子功能. 在非模板化设置中,我会这样做:
algo.h将仅包含针对最终用户的声明(可通过include访问)algo.cppalgo.cpp,让我大功能于algo.cpp(一宣布algo.h)使用它们,而不是让他们给最终用户访问.如果这些子功能本身不是模板化的,而是由模板化函数使用,则这不再起作用.模板化的子功能可以进入.tpp文件,被模板化的"大功能"使用,一切都很好.
但是,如果这些功能是非模板化的,如果放在文件中,它们会导致多个定义错误(这是我之前的问题所在).tpp.另一方面,如果它们位于单独的.cpp文件中,它们或者最终用户可以访问(如果我将声明放在.h文件中),或者对于要使用它们的大函数是不可访问的(如果我不放.cpp文件外的声明).
组织函数的正确方法是什么,有些是模板化的,有些不是,有些应该是最终用户可以访问的,有些则不是,可以访问多个文件?
理想情况下,(对于完整性),我在寻找答案应该解决的位置如下(在.h,.tpp,.cpp,或其他相应的文件):
很多时候,当我看到其他人的代码时,我看到一些包括.h文件,有些包括.c/.cpp文件.有什么不同?
我有一个与此类似的问题:
但他们使用的解决方法对我不起作用。
我有一个带有静态数据成员的 CRTP 类,其中一个是 std::mutex。不幸的是,GCC 的 (4.8.2) 链接器给了我这个互斥锁的“未定义引用”错误。Clang (3.4) 没有。有解决方法吗?最初的问题(上面链接)在静态数据成员上调用了复制构造函数,迫使 GCC 发出一个符号,但由于我的数据成员是 std::mutex,这不是一个选项——复制构造函数被删除,然后没有参数构造函数。我只是被冲洗了吗?
我不相信问题出在 std::mutex 上,我认为问题在于 GCC 如何处理依赖默认构造函数的模板类中的静态数据成员。
谢谢你的帮助!
这是我的问题的精简版:test.hh
#include <mutex>
template < class T >
class CRTP_class {
public:
T * ptr_;
static std::mutex mutex_; // linker error here
static int clearly_a_problem_with_mutex_; // no linker error here
};
class Foo : public CRTP_class< Foo >
{
public:
void set_bar( int setting );
int bar_;
};
Run Code Online (Sandbox Code Playgroud)
测试.cc
#include <test.hh>
template<> std::mutex CRTP_class< Foo >::mutex_;
template<> int CRTP_class< …Run Code Online (Sandbox Code Playgroud) 由于某种原因,C++ 似乎不喜欢将模板类(即声明为 的类template <typename T> class Thing)拆分为.h和 一个.cpp文件,就像处理任何其他类一样。
这是否意味着在编写模板类时,我应该将其全部写入头文件中?在这些情况下,C++ 程序员会做什么?
编辑:我知道还有其他方法可以将其全部写入.h文件中。但最好的选择是什么?或者最常见的选择是什么?
c++ ×5
templates ×4
c ×1
c++11 ×1
declaration ×1
difference ×1
gcc ×1
header ×1
header-files ×1
include ×1