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

如何无需额外变量直接将constexpr用作右值?

无需额外变量直接使用constexpr调用的方法?

是否存在无需创建额外变量即可使用constexpr的方法?以下面的代码为例(该代码将类型映射至全局对象,映射原因与问题无关):

#include <iostream>

struct S { int val; };

S one{1};
S two{2};

template<typename>
constexpr S& get() = delete;

template<>
constexpr S& get<int>() { return one; };

template<>
constexpr S& get<double>() { return two; };

auto main() -> int {

    constexpr auto& type = get<int>();

    std::cout << type.val << std::endl;
    std::cout << get<double>().val << std::endl;
    return 0; 
}

调用get<double>()不会被视为constexpr,会在运行时执行(开启优化后会被内联,效果等同于constexpr);而constexpr auto& type = get<int>()这种方式虽利用了constexpr,但需要额外变量。出于易用性考虑,是否存在类似std::cout << (constexpr get<int>()) << std::endl;的可行写法?


可行方案

方案1:使用立即调用的constexpr lambda(C++20+)

你可以借助立即执行的constexpr lambda,直接在表达式中触发get()的编译期求值,无需额外变量:

std::cout << ([]() constexpr { return get<int>(); }()).val << std::endl;

这种写法会强制lambda在编译期执行,从而让get<int>()以constexpr方式求值,最终直接在编译期确定要访问的全局对象。

方案2:改用consteval修饰函数特化(C++20+)

如果你的场景不需要get()函数支持运行时调用,可以把特化版本的constexpr改成consteval:

template<>
consteval S& get<int>() { return one; };

// 直接调用就会强制在编译期求值
std::cout << get<int>().val << std::endl;

consteval是C++20引入的关键字,标记的函数必须在编译期完成求值,因此直接调用get<int>()时会自动触发编译期计算,不需要额外变量或修饰。

注意事项

  • 两种方案都需要C++20或更高版本的编译器支持;
  • 如果需要保留get()函数的运行时可用性,方案1的constexpr lambda是更灵活的选择;方案2的consteval会完全限制函数只能在编译期使用。

内容的提问来源于stack exchange,提问作者Lucas Mülling

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:45:40