Jac*_*mme 1 c++ constants clang header-files c++17
我正在创建一个仅包含 C++ 标头的库实现,其中定义了多个我static constexpr只想在库中使用的常量(定义为 s),以使我的代码更加清晰易读。我认为拥有内部链接足以从我包含此库的任何其他源文件中“隐藏”这些常量。
但是,在将此标头包含在我正在为其编写单元测试的另一个文件中之后,我收到了类似的错误redefinition of '<constant_name>'(测试源文件有自己的同名常量,因为它们在某些测试用例中很有用,也定义为static constexprs)。经过进一步阅读后,我现在了解到内部链接意味着常量在翻译单元之外不可用,但翻译单元包括源文件及其包含的任何标头。这可以解释为什么我会收到该redefinition错误,因为测试源文件和库头文件中都存在具有相同名称的常量,并且它们最终成为单个翻译单元。
目前,我已将上述常量包装在命名空间中以避免冲突。然而,这并不理想。例如,当我使用命名空间作为前缀时,我仍然会在其他文件中获得这些常量的自动完成建议。相反,我希望它们完全隐藏。
我的问题是是否有办法解决这个问题。有没有某种方法可以使这些常量仅在标头本身内真正可见,并且对包含它的任何文件不可见?
编辑:这里有一些代码来演示我的意思。
library.hpp
static constexpr int USEFUL_CONSTANT = 5;
namespace library {
...library implementation here...
}
Run Code Online (Sandbox Code Playgroud)
tests.cpp
#include "library.hpp"
// Constant happens to be useful in tests too, but I don't
// want to expose it for everybody, so I redefine it here
static constexpr int USEFUL_CONSTANT = 5;
...tests here...
Run Code Online (Sandbox Code Playgroud)
我收到重新定义错误,因为这两个常量都是同一翻译单元的一部分。
一些可行的方法:
namespace mylib
{
namespace detail
{
inline constexpr int const goodenough{42};
}
int foo(void)
{
return detail::goodenough;
}
}
Run Code Online (Sandbox Code Playgroud)
private static授予访问权限friendnamespace mylib
{
int foo(void);
class detail
{
friend int ::mylib::foo(void);
static inline constexpr int const goodenough{42};
};
int foo(void)
{
return detail::goodenough;
}
}
Run Code Online (Sandbox Code Playgroud)
注:constexpr暗示着inline和const。