如何编写支持T与const T范围的C++20函数?
适配常量与非常量连续范围的
foo函数实现 你当前的foo函数模板在处理常量连续范围(比如const std::vector<std::string>&)时会编译失败:模板推导的T为std::string,但常量范围的元素不可修改,对应的span应该是std::span<const std::string>,而非std::span<std::string>,类型不匹配导致编译错误。
解决方案1:自动推导span类型(推荐)
通过让函数返回值和内部span自动适配输入范围的常量性,无需手动指定T的默认值,代码更简洁且兼容性更好:
template<std::ranges::contiguous_range R> auto foo(R&& r, const std::ranges::range_value_t<std::remove_reference_t<R>>& someValue) { auto sp = std::span{r}; // 自动推导span类型:非const范围→span<T>,const范围→span<const T> /// ... 你的业务逻辑代码 return sp; }
适配逻辑说明:
- 传入非
const的std::vector<std::string>或std::span<std::string>时,std::span{r}推导出std::span<std::string>,返回值类型同步匹配; - 传入
const std::vector<std::string>&时,std::span{r}自动推导为std::span<const std::string>,完美适配常量范围的元素属性,编译通过。
解决方案2:显式控制T的const修饰
如果你需要保留显式的模板参数T,可以通过条件模板来根据输入范围的const属性调整T的类型:
template< std::ranges::contiguous_range R, typename T = std::conditional_t< std::is_const_v<std::remove_reference_t<R>>, const std::ranges::range_value_t<R>, std::ranges::range_value_t<R> > > std::span<T> foo(R&& r, const T& someValue) { std::span<T> sp{r}; /// ... 你的业务逻辑代码 return sp; }
这里利用std::conditional_t判断输入范围是否为const,自动为T添加或移除const修饰,确保std::span<T>的类型与输入范围的元素属性一致。
内容的提问来源于stack exchange,提问作者rodrigocfd
相关产品推荐
相关产品推荐

