C++20泛型lambda存储任意类型编译期值接口优化问题求解
问题根源
该报错由C++模板消歧义规则触发:origin是泛型lambda的实例,属于推导得到的依赖类型,当调用其模板化operator()时,编译器默认会将<解析为小于运算符,而非模板参数的起始标识,因此抛出「非模板实体后跟模板参数」的错误。
解决方案
仅需修改两处代码,通过.template关键字显式告知编译器后续为模板调用即可,完全不需要调整你定义的公共接口:
#include <type_traits> #include <iostream> template<int I> consteval auto addItem(auto origin, auto value) // 1. requires检查处添加.template消歧义 requires (std::is_same_v<void, decltype(origin.template operator()<I>())>) { auto result = [=]<int J>() constexpr { if constexpr(I == J) { return value; } else { // 2. 递归调用处添加.template消歧义 return origin.template operator()<J>(); } }; return result; } int main() { constexpr auto c = []<int I>() {}; constexpr auto c_ = addItem<1>(c, "Hello"); constexpr auto c__ = addItem<2>(c_, 42); std::cout << c__<1>() << " "; std::cout << c__<2>() << "\n"; }
修改后的代码可正常编译运行,输出结果为Hello 42,原有约束逻辑完全保留:重复添加同一个索引会触发requires子句的编译报错,访问未注册的索引会因返回void触发编译失败,符合预期需求。
内容的提问来源于stack exchange,提问作者Markus W.
相关产品推荐
相关产品推荐

