C++如何声明指定元素类型的std::ranges::range模板参数?
错误原因
std::ranges::range 概念本身仅接收「要检查是否为范围的类型」作为唯一模板参数,你写的 std::ranges::range<int> 相当于在判断 int 类型是不是合法范围,显然不满足约束,因此编译失败。
要约束范围的元素类型,需要组合使用范围概念和类型比对概念:
正确写法
写法1:配合requires子句直接约束(C++20通用写法)
搭配 std::ranges::range_value_t 获取范围的元素类型,用 std::same_as 严格约束类型为int:
#include <ranges> #include <concepts> #include <vector> #include <views> template <std::ranges::range Range> requires std::same_as<std::ranges::range_value_t<Range>, int> inline auto TransformIt(Range r) { return r | std::views::transform([](int n) { return n * n; }); } int main() { std::vector<int> v; auto r = TransformIt(v); return 0; }
如果允许元素可以隐式转换为int,可以把std::same_as替换为std::convertible_to。
写法2:自定义复用型范围元素约束概念
如果需要频繁用到带元素类型约束的范围,可以提前自定义概念简化后续写法:
// 自定义带元素类型约束的范围概念 template <typename R, typename ElemType> concept range_of = std::ranges::range<R> && std::same_as<std::ranges::range_value_t<R>, ElemType>; // 直接使用自定义概念,语法和你最初尝试的写法一致 template <range_of<int> Range> inline auto TransformIt(Range r) { return r | std::views::transform([](int n) { return n * n; }); }
写法3:缩写模板语法(更简洁)
用C++20的auto模板参数语法,写法更短:
inline auto TransformIt(std::ranges::range auto r) requires std::same_as<std::ranges::range_value_t<decltype(r)>, int> { return r | std::views::transform([](int n) { return n * n; }); }
内容的提问来源于stack exchange,提问作者Dmitriano
相关产品推荐
相关产品推荐

