C++20使用std::views时模板函数类型推导失败问题咨询
问题原因解释
你遇到的模板推导失败,本质是函数模板名本身无法作为类型确定的实体,直接传给同样需要推导模板参数的std::views::transform,具体逻辑如下:
length是函数模板而非具体函数实例,当你不指定模板参数直接写length时,它没有确定的类型,必须结合上下文才能推导出对应的实例化版本。std::views::transform本身也是模板,它接收的可调用对象参数的类型属于待推导的模板参数。这就形成了推导死锁:编译器需要先确定length的类型才能推导transform的模板参数,但length的实例化又需要先知道transform要求的可调用对象类型,才能推导出自己的模板参数E。- C++的模板推导规则不支持这种双向推导,该场景属于标准定义的模板非推导上下文,因此推导失败报匹配错误。
其他可行写法
你原来显式指定length<E>的写法是正确的,相当于直接给了编译器确定的函数实例,transform的模板参数可以直接完成推导。如果你不想显式指定模板参数,也可以用泛型lambda包一层实现自动推导:
template<typename E> auto getLengths(const std::vector<E>& v) { return v | std::views::transform([](const auto& elem) { return length(elem); }); }
这种写法下lambda本身是类型确定的可调用对象,可以正常完成transform的参数推导;lambda被调用时elem类型已知为E,也能自动推导出length的模板参数。
非模板函数可以正常工作的原因也很简单:非模板函数本身有固定的确定类型,不需要额外推导,自然可以直接匹配transform的参数要求。
内容的提问来源于stack exchange,提问作者DS_London
相关产品推荐
相关产品推荐

