英文:
Creating a namespace with code that is organized into different folders, and having a master header for library?
问题
以下是您要翻译的部分:
"So I have project (named "vira") which produces both a shared library AND a set of executables (essentially some convenient tools built with the library for simple operations). Below is a simplified outline of the project to hopefully outline my question:
| - external/
|
| - include/
| | - vira/
| | - models/
| | - importers/
| | - import_maplet.hpp
| - lib/
| | - models/
|
| - src/
Where external/
contains source code (unedited by this project) for small dependencies. include/vira/
contains all of the public headers, lib/
contains all of the implementation (and private headers) for the library, and src/
contains all of the headers/implementation for the executables. As you can see, the files in the lib/
directory are organized in subdirectories to try to group things together in a meaningful way.
I'm thinking of adding the entire library to a Vira
namespace. However I'm unsure how exactly that would work with the folder structure I currently have (or if my folder structure is problematic).
Currently, to include import_maplet.hpp
you would need to use:
#include "vira/models/importers/import_maplet.hpp"
When I look at other projects though, there is never such a mess of a long include statement. Take the chrono
library for example. We simply using include <chrono>
and now if we want to access the high resolution time right now, we then call in the code:
std::chrono::high_resolution_clock::now();
This seems like a more elegant solution. Or at least, this seems to be the solution that is more common in the c++ I have seen.
My first assumption on how to capture this kind of behavior is to keep my file structure, but then provide a "top level" header such as Vira.hpp
and then setup a Vira
namespace, a Models
namespace, and an Importers
namespace that are nested together such that you can simply use:
Vira::Models::Importers::import_maplet();```
Taking a look at some other projects such as [eigen](https://gitlab.com/libeigen/eigen/-/blob/master/Eigen/Core) do it, where you only need to do the following to include large swaths of the library:
```#include <Eigen/Eigen>
#include <Eigen/Core>```
But it leaves me with a two questions:
1. While this approach seems common, I've also read that doing it this way will dramatically increase build time as it is including tons of headers, most of which would be unneeded. Does that mean that this style of thing is something I should avoid entirely?
2. Whether I do it that way or not, should my code be organized into a namespace? It seems clunky to need both `include "vira/models/importers/import_maplet.hpp"` *and* to need to use `Vira::Models::Importers::import_maplet();`"
<details>
<summary>英文:</summary>
So I have project (named "vira") which produces both a shared library AND a set of executables (essentially some convenient tools built with the library for simple operations). Below is a simplified outline of the project to hopefully outline my question:
vira/
| - external/
|
| - include/
| | - vira/
| | - models/
| | - importers/
| | - import_maplet.hpp
| - lib/
| | - models/
|
| - src/
Where `external/` contains source code (unedited by this project) for small dependencies. `include/vira/` contains all of the public headers, `lib/` contains all of the implementation (and private headers) for the library, and `src/` contains all of the headers/implementation for the executables. As you can see, the files in the `lib/` directory are organized in subdirectories to try to group things together in a meaningful way.
I'm thinking of adding the entire library to a `Vira` namespace. However I'm unsure how exactly that would work with the folder structure I currently have (or if my folder structure is problematic).
Currently, to include `import_maplet.hpp` you would need to use:
#include "vira/models/importers/import_maplet.hpp"
When I look at other projects though, there is never such a mess of a long include statement. Take the `chrono` library for example. We simply using `include <chrono>` and now if we want to access the high resolution time right now, we then call in the code:
std::chrono::high_resolution_clock::now();
This seems like a more elegant solution. Or at least, this seems to be the solution that is more common in the c++ I have seen.
My first assumption on how to capture this kind of behavior is to keep my file structure, but then provide a "top level" header such as `Vira.hpp` and then setup a `Vira` namespace, a `Models` namespace, and an `Importers` namespace that are nested together such that you can simply use:
#include "Vira"
Vira::Models::Importers::import_maplet();
Taking a look at some other projects such as [eigen](https://gitlab.com/libeigen/eigen/-/blob/master/Eigen/Core) do it, where you only need to do the following to include large swaths of the library:
#include <Eigen/Eigen>
#include <Eigen/Core>
But it leaves me with a two questions:
1. While this approach seems common, I've also read that doing it this way will dramatically increase build time as it is including tons of headers, most of which would be unneeded. Does that mean that this style of thing is something I should avoid entirely?
2. Whether I do it that way or not, should my code be organized into a namespace? It seems clunky to need both `include "vira/models/importers/import_maplet.hpp"` *and* to need to use `Vira::Models::Importers::import_maplet();`
</details>
# 答案1
**得分**: 1
无论像 `Eigen/Eigen` 这样的头文件是否 "糟糕" 取决于它们的使用方式以及替代方案。如果替代方案会导致你包含几乎所有 `Eigen/Eigen` 包含的头文件,那么仅包含 `Eigen/Eigen` 通常不会有明显的不利影响。然而,如果 `Eigen/Eigen` 包含了 20 个头文件,而你实际上只需要其中一个…… 那么在构建时可能会产生可衡量的影响。
关于命名空间,有几点需要考虑:
1. 命名空间不必与文件夹/包含结构匹配。将项目中的所有内容放在一个命名空间下或者拥有比头文件更多的命名空间可能是有意义的。这将取决于你的项目的大小和目的。
2. 繁琐的命名空间可以通过在 cpp 文件的顶部添加 `using namespace my::long::namespace`(以获取整个命名空间的访问权限)或者 `using my::long::namespace::class_i_want`(以获取命名空间中的单个类的访问权限)来避免。然后,你就可以直接使用 `class_i_want` 而不需要加上命名空间。
<details>
<summary>英文:</summary>
Whether or not headers such as `Eigen/Eigen` are "bad" depends on how they are used and what the alternative is. If the alternative would lead to you including nearly all of the headers that `Eigen/Eigen` includes, then there is generally no significant downside to just including `Eigen/Eigen`. However, if `Eigen/Eigen` includes 20 headers and you really only need one... there could be a measurable impact to build times.
In regards to namespaces, there are a few things to consider:
1. namespaces do not have to match the folder/include structure. It may make sense to put everything in your project under one namespace or to have more namespaces than includes. This will depend on the size and purpose of your project.
2. Cumbersome namespaces can be worked around with `using namespace my::long::namespace` (to get access to the whole namespace) or `using my::long::namespace::class_i_want` (to get access to a single class in the namespace) added to the top of a cpp file. Then you can just use `class_i_want` without a namespace.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论