内联 constexpr 和匿名命名空间变量?
Inline constexpr and anonymous namespace variables?
我有以下问题。在 .hpp 文件中,我有一个必须使用命名空间全局变量的函数 Space::foo()
,我想将它隐藏在匿名命名空间中。但现在我想知道,我是否有风险在每个翻译单元中定义 values
多个副本,或者只有一个?感谢您的帮助。这是因为我需要 Space
命名空间中的一堆函数和一种私有数据部分(匿名命名空间的东西),这样 Space
有点像 class只有静态成员,但如果我在不同的单元中包含 .hpp 文件,我不想拥有这些变量的多个副本。
// .hpp file
#include <array>
namespace Space {
namespace {
constexpr std::array<int, 10000> fill() { /* ... */ };
inline constexpr std::array<int, 10000> values = fill();
}
inline int foo(int i) {
return values[i];
}
}
do I risk having values defined in each translation unit with multiple copies
是的。您将在每个 TU 中有一个 values
的定义。您也不能声明它 extern constexpr
因为 [dcl.constexpr]
/1 说“The constexpr
说明符应仅应用于 definition变量".
由于目的似乎是能够选择常量值已评估,因此您可以使 fill
和 foo
[=18] =] 并跳过 <anonymous>::values
.
namespace Space {
namespace {
consteval std::array<int, 10000> fill() {
return {}; // replace with your filling algorithm
};
}
inline consteval int foo(size_t i) {
return fill()[i];
}
inline consteval int bar(size_t i, size_t j) {
constexpr auto values = fill();
return values[i] + values[j];
}
}
这将使 foo
和任何其他 consteval
函数可以使用 fill()
中的算法并使用 constexpr
/[=18 中的结果=] 情况。
constexpr auto x = Space::bar(10, 20);
我有以下问题。在 .hpp 文件中,我有一个必须使用命名空间全局变量的函数 Space::foo()
,我想将它隐藏在匿名命名空间中。但现在我想知道,我是否有风险在每个翻译单元中定义 values
多个副本,或者只有一个?感谢您的帮助。这是因为我需要 Space
命名空间中的一堆函数和一种私有数据部分(匿名命名空间的东西),这样 Space
有点像 class只有静态成员,但如果我在不同的单元中包含 .hpp 文件,我不想拥有这些变量的多个副本。
// .hpp file
#include <array>
namespace Space {
namespace {
constexpr std::array<int, 10000> fill() { /* ... */ };
inline constexpr std::array<int, 10000> values = fill();
}
inline int foo(int i) {
return values[i];
}
}
do I risk having values defined in each translation unit with multiple copies
是的。您将在每个 TU 中有一个 values
的定义。您也不能声明它 extern constexpr
因为 [dcl.constexpr]
/1 说“The constexpr
说明符应仅应用于 definition变量".
由于目的似乎是能够选择常量值已评估,因此您可以使 fill
和 foo
[=18] =] 并跳过 <anonymous>::values
.
namespace Space {
namespace {
consteval std::array<int, 10000> fill() {
return {}; // replace with your filling algorithm
};
}
inline consteval int foo(size_t i) {
return fill()[i];
}
inline consteval int bar(size_t i, size_t j) {
constexpr auto values = fill();
return values[i] + values[j];
}
}
这将使 foo
和任何其他 consteval
函数可以使用 fill()
中的算法并使用 constexpr
/[=18 中的结果=] 情况。
constexpr auto x = Space::bar(10, 20);