内联 constexpr 和匿名命名空间变量?

时间:2021-02-04 07:17:52

标签: c++ inline constexpr c++20 linkage

我有以下问题。在 .hpp 文件中,我有一个函数 Space::foo() 必须使用命名空间全局变量,我想将它隐藏在匿名命名空间中。但现在我想知道,我是否冒着在每个翻译单元中定义 values 多个副本的风险,还是只有一个?谢谢你的帮助。这是因为我需要 Space 命名空间中的一堆函数以及一种私有数据部分(匿名命名空间的东西),所以 Space 有点像一个只有静态成员的类,但如果我以不同的单位包含 .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];
  }
}

1 个答案:

答案 0 :(得分:1)

<块引用>

我会冒险在每个翻译单元中定义多个副本的值吗

是的。您将在每个 TU 中有一个 values 定义。您也不能声明它 extern constexpr,因为 [dcl.constexpr]/1 说“constexpr 说明符应仅应用于变量的定义”。

由于目的似乎是能够选择恒定的值求值,您可以同时使 fillfoo consteval 并跳过 { {1}}。

<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 中使用结果情况。

consteval