内联 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变量".

由于目的似乎是能够选择常量值已评估,因此您可以使 fillfoo [=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);