如何无需额外变量直接将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
相关产品推荐
相关产品推荐

