定义一个基于 constexpr 数组变换的数组

define an array based on constexpr array transform

有没有办法通过从现有数组转换来定义新数组,其中两个数组都是编译时已知的 constexpr 数组,如下所示:

constexpr array<string_view, 3> arr{"foo", "bar", "alpha"};
for (auto o : arr) {
  std::cout << ' ' << o;
}
std::cout << '\n';

constexpr array<size_t, arr.size()> arr2{0};
for (auto o : arr2) {
  std::cout << ' ' << o;
}
std::cout << '\n';

std::transform(arr.begin(), arr.end(), arr2.begin(),
               [](auto e) { return e.size(); });

// arr2: {3, 3, 5}
static_assert(arr2[2] == 3);

此代码无法编译,即使在 c++20 中它添加了 std::transformconstexpr 版本,错误:

In file included from /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/algorithm:62,
             from <source>:1:
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_algo.h: In instantiation of 'constexpr _OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation) [with _IIter = const std::basic_string_view<char>*; _OIter = const long unsigned int*; _UnaryOperation = main()::<lambda(auto:16)>]':
<source>:29:50:   required from here
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_algo.h:4296:19: error: assignment of read-only location '* __result'
4296 |         *__result = __unary_op(*__first);
  |         ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
<source>: In function 'int main()':
<source>:31:25: error: static assertion failed
31 |   static_assert(arr2[2] == 3);

您可以编写一个 returns 数组的函数,并使用它来初始化 constexpr 变量。示例:

constexpr auto make_the_array = [=] {
    std::array<std::size_t, arr.size()> temp_arr{0};
    auto get_size = [](auto e) { return e.size(); };
    std::transform(arr.begin(), arr.end(),
         temp_arr.begin(), get_size);
    return temp_arr;
};
constexpr auto arr2 = make_the_array();