假设我正在编写一个仅包含标题或主要包含标题的库,并且具有以下代码:
using my_type = int;
namespace detail {
inline void foo() { my_type x; do_foo_stuff(x); }
}
inline void bar() { do_bar_stuff(); detail::foo(); }
inline void baz(my_type y) { do_baz_stuff(y); detail::foo(); }
我要放置
foo()
在不同的文件中。动机是我有很多这样的详细和不详细的函数,我希望带有我的公共(public) API 的标题不会被 detail
中出现的内容弄乱。 ,并且不适合直接使用。问题是 - 这样做的惯用方法是什么?
detail::
的文件我的公共(public) header 末尾的代码 - 因为声明需要在使用时进行。 detail::
的文件我的公共(public) header 开头的代码 - 因为它们依赖于一些公共(public)定义,例如类型和常量。让我们假设它们不依赖任何函数。 所以它不能是这两个选项之一。
最佳答案
因为通常头文件包含声明,而源文件包含实现,所以人们认为头文件是接口(interface)、公共(public) api,而源文件包含实现细节。在库中,用户(库的消费者)看不到源文件的内容,但可以看到标题,这一事实进一步强化了这一点。
然而这是错误的:
头文件和源文件的分离不是在公共(public)接口(interface)/实现屏障上完成的。这种代码分离只是 C++ 及其 C 遗产的设计方式的产物。 C++ 不需要多遍编译器,因此它需要在使用前声明和一个定义。所以标题是一个解决方案。它们不是 API 规范。
所以不幸的结论是 C++ 没有 API/实现分离,尝试使用 header 是不成功的。
现在回答您的问题:我所知道的惯用方式确实是使用
details
或 impl
命名空间。据了解,以这种方式命名的命名空间包含库实现细节,不应在用户代码中使用。我个人不会改变你最初的设计。C++20 终于引入了模块,afaik 解决了这个问题。现在,我们将在消费者和公共(public) API 中看不到的内部符号明确区分开来。
关于c++ - 让细节命名空间代码看不见 - 优雅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60960693/