正确组织最终用户无法访问的模板化和非模板化功能
Proper organization for a mixture of templated and non-templated functions not accessible to the end-user
在我正在做的一个项目中,我目前正在实现一个模板化的算法。我在组织函数声明和定义时遇到了一些问题,因为涉及到模板(我在这里问了一个关于如何处理非模板函数与模板函数"分组"在一起的问题)。然而,这使我对这些文件的一般正确组织产生了疑问。
我想把所有的定义和所有的声明分开(只是为了可读性,即使我不得不在声明中包含模板化的定义)。
我得到的答案建议组织如下:
- 所有函数声明的声明文件
algo.h
-
模板化的定义文件
algo.tpp
将包含在algo.h
中(模板需要在编译时声明) - (非模板化的)定义文件
algo.cpp
不包含在任何地方。
如果所有定义的函数都应该对最终用户可见(即所有声明都在algo.h
文件中),则此方法工作得很好。然而,有时我喜欢把我的大函数分解成更小的功能,但是我希望最终用户只能访问"大函数",而不能访问它们的子部分。在非模板设置中,我会这样做:
- 声明文件
algo.h
将只包含用于最终用户的声明(可通过include访问) 这些函数的定义将进入 - 子功能的定义(和声明)将只出现在
algo.cpp
中,允许我的大函数在algo.cpp
中使用它们(在algo.h
中声明的那个),但不能使最终用户访问它们。
algo.cpp
如果这些子功能本身没有被模板化,而是被模板化的函数使用,则不再工作。模板化的子功能可以放到.tpp
文件中,由模板化的"大函数"使用,一切都很好。
然而,如果这些功能是非模板化的,如果放在.tpp
文件中,它们将导致多个定义错误(这就是我之前的问题)。另一方面,如果它们在单独的.cpp
文件中,它们要么对最终用户可访问(如果我将声明放在.h
文件中),要么对打算使用它们的大函数不可访问(如果我没有将声明放在.cpp
文件之外)。
组织函数的正确方式是什么,有些是模板化的,有些不是,其中一些应该是最终用户可以访问的,而有些不是,放在多个文件中?
理想情况下,(为了完整性),我正在寻找的答案将解决以下问题(在.h
, .tpp
, .cpp
或其他适当的文件中):
- 模板化客户端函数
- 非模板客户端函数
- 模板化客户端函数
- 非模板客户端函数
- 上述所有声明(当使用声明时)
简短的伪代码我想要的功能示例(没有文件分隔)
// Templated sub-functionality, used by bigFunctionality,
// but ideally not accessible to the end-user
// This might not be possible since it is templated,
// so I am content with putting it in the .tpp file
template <typename Compare>
void subFunctionality(Compare order, .. args ..){ /* impl */ }
// Non-templated sub-functionality, used by
// bigFunctionality, but NOT accessible to the end-user
void moreSubFunctionality(.. args ..) { /* impl */ }
// the main functionality, meant to be
// accessible to everybody across all files:
template <typename Compare>
void bigFunctionality( .. non-templated args ..., Compare order){
subFunctionality(order, .. args ..);
moreSubFun(.. args ..);
// more stuff
}
再一次,我正在寻找如何将其分离到多个文件(即使它们彼此包含在一起,因为它必须与模板一起完成),部分出于可读性目的,部分出于可访问性。
澄清一下,这些是算法-->函数,而不是类。(我知道将模板化和非模板化的函数放入同一个模板化类中可以解决我的问题)。
PS:我知道问题的标题又大又长,所以如果有人有缩短它的想法,我将非常高兴得到建议/编辑
这是c++中没有模块的一个不幸的副作用:声明的内容必须是可见的。
一般来说,指导方针是简单地使用"私有"命名空间(嵌套在用户可见的命名空间中):- 使用清晰的名称(如
internal
) - 并在
.tpp
文件 的命名空间中声明这些辅助函数
然后,说明这个名称空间是内部的,不适合客户端调用者。如果可能的话,还应该注释命名空间/函数,这样就不会为它们生成文档。
此时,这些函数是明显私有的和隐藏的。如果你想更进一步,你可以简单地在class
(*)中声明它们private
,然后只有你的函数是这个类的friend
。然后,任何使用它们的尝试都会导致编译器发出一个错误:它们是可见的,但是不可访问。然而,大多数人(从Boost开发人员开始)只是不麻烦,我当然也不会。
(*) class
基本上取代了私有命名空间。
- 如何从其他功能C++访问参数?
- 如何使用 MPI 的远程内存访问 (RMA) 功能并行化数据聚合?
- 访问我以前可以访问的功能时出现分段错误
- 好友功能 - 成员无法访问
- 如何启用友元类的友元功能直接在C++中访问其私有成员
- 无法从好友功能访问类的私有成员?"ostream"不是"std"的成员?
- 无法访问公共功能? 没有指定成员?
- 好友功能仍无法访问私人会员
- 我无法获得好友会员功能以实际访问私人会员
- GPU设备函数如何访问主机功能中定义的对象
- 派生类中的成员字段别名(无访问器功能)
- 从C文件访问C 类成员功能
- 访问嵌套结构的数据成员并将结构传递到功能C
- 尝试在 qt 中建立访问器功能
- (C )创建可以从功能访问的动态全局数组/向量
- 无法从类中的其他功能访问同一类的变量
- 防止朋友功能访问班级的私人会员
- 使用类成员功能访问私有结构
- 成员无法使用好友功能访问
- 无法从其他类的功能访问对象的参数