You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否使用constexpr函数初始化constexpr std::array?

Creating a Constexpr Array with Flexible Size (Elements 1..N-1 Followed by 0)

Absolutely, you can achieve this requirement! Let's break down why your original code might be failing, then walk through a few solid solutions that let you adjust the array size easily while keeping everything computed at compile time.

Why Your Original Code Throws an Error?

Starting with C17, constexpr functions do allow simple for loops, but older versions of MSVC might have spotty support for constexpr loops, or maybe your project isn't set to use a new enough C standard (like still targeting C++14). No worries though—we've got workarounds and cleaner approaches.

Solution 1: C++20 Ranges (Cleanest & Most Readable)

If your compiler supports C++20, this is the way to go. No manual loops needed, and resizing is just changing a single value:

#include <array>
#include <ranges>
#include <algorithm>

template<size_t N>
constexpr std::array<int, N> getFinalTable() {
    std::array<int, N> result{};
    // Generate 1 to N-1, copy into the array, then set last element to 0
    auto iota_sequence = std::views::iota(1, static_cast<int>(N));
    std::ranges::copy(iota_sequence, result.begin());
    result.back() = 0;
    return result;
}

// Usage example:
constexpr size_t DesiredSize = 9;
constexpr std::array<int, DesiredSize> final_table = getFinalTable<DesiredSize>();

Just tweak DesiredSize whenever you need a different array length—everything adapts automatically.

Solution 2: Template Metaprogramming (C++14 Compatible)

If you need to support older C++ standards, template recursion and index sequences let us build the array entirely at compile time:

#include <array>
#include <utility>

template<size_t N, size_t... Indices>
constexpr std::array<int, N> buildFinalTable(std::index_sequence<Indices...>) {
    // For each index: use 0 if it's the last element, else index+1
    return {{(Indices == N-1 ? 0 : static_cast<int>(Indices) + 1)...}};
}

template<size_t N>
constexpr std::array<int, N> getFinalTable() {
    return buildFinalTable<N>(std::make_index_sequence<N>{});
}

// Usage example:
constexpr std::array<int, 9> final_table = getFinalTable<9>();

This uses compile-time template expansion, so there's zero runtime overhead, and it works with any C++14-compliant compiler.

Solution 3: Fix Your Original Loop (C++17+)

If you prefer sticking with your loop approach, make sure your project is set to use C++17 or later, and adjust the loop to be more compiler-friendly:

#include <array>

constexpr std::array<int, 9> getFinalTable(){
    std::array<int, 9> result{};
    // Use result.size() instead of hardcoding 9 for better maintainability
    for (size_t i = 0; i < result.size() - 1; ++i) {
        result[i] = static_cast<int>(i) + 1;
    }
    result.back() = 0;
    return result;
}

// Usage example:
constexpr std::array<int, 9> final_table = getFinalTable();
// To resize, just change the array's template parameter (the 9)

In Visual Studio, go to your project properties → C/C++ → Language → set "C++ Language Standard" to ISO C++17 Standard (/std:c++17) or higher, and this should compile without issues.

All these approaches let you create the exact array you want at compile time, and adjusting the size is trivial—no need to rewrite core logic.

内容的提问来源于stack exchange,提问作者Franz Kafka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 15:47:48