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

consteval函数取址编译错误排查与解决(Project Euler 206)

问题解答

错误原因

consteval 函数属于立即函数,必须在编译阶段完全求值,且不允许获取其地址(这类函数在运行时没有可寻址的实体)。你的代码中,将 check_if_square_has_special_form 传递给 ranges::find_if 时,算法需要捕获该函数的地址来后续调用,这直接违反了 consteval 函数的使用规则。此外,concealed_square 未标记为 consteval 或 constexpr,导致范围操作会在运行时执行,但 consteval 函数无法在运行时被调用。

解决方法

要实现编译期解决方案,需用编译期循环替代运行时的范围查找,直接在 consteval 函数内调用检查逻辑,避免获取函数地址:

  1. 将 concealed_square 标记为 consteval,确保整个函数在编译期求值。
  2. 利用问题特性缩小遍历范围:目标平方数是形如 1_2_3_4_5_6_7_8_9_0 的19位数,因此x是10位数,且末尾必须为0(因为平方末尾是0),起始值可设为 1010101010(最小符合开头的平方数的平方根),步长设为10以减少迭代次数。
  3. 调整变量类型为 long long,避免平方运算时的溢出。

修正后的代码

#include <cstdlib>
#include <print>

using namespace std;

consteval bool check_if_square_has_special_form(long long x) {
    long long square = x * x;

    // 检查模式:...1_2_3_4_5_6_7_8_9_0
    for (const int expected_digit : {0, 9, 8, 7, 6, 5, 4, 3, 2, 1}) {
        if (square % 10 != expected_digit) {
            return false;
        }
        square /= 100;
    }
    return true;
}

consteval long long concealed_square() {
    // 目标平方数的范围对应的x区间
    constexpr long long start = 1010101010;
    constexpr long long end = 1389026623;

    // x必须以0结尾,步长设为10
    for (long long x = start; x <= end; x += 10) {
        if (check_if_square_has_special_form(x)) {
            return x;
        }
    }

    // 根据题目描述,必有唯一解,此处为不可达代码
    return -1;
}

int main() {
    println("The answer is {}", concealed_square());
    return EXIT_SUCCESS;
}

代码说明

  • check_if_square_has_special_form 保持 consteval,确保仅在编译期被调用。
  • concealed_square 作为 consteval 函数,在编译期完成循环查找,直接调用检查函数(无地址传递)。
  • 缩小遍历范围和步长优化,大幅减少编译期需要检查的数字数量,提升编译效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:34:55