C++中如何简洁声明仅接收string类型元素range的函数
解决方案
你想要的简洁写法完全可以实现,核心是不需要使用模板模板参数。你之前的实现不仅繁琐,还存在适配范围窄的问题:仅支持单参数模板实例化的容器,无法适配std::array<std::string, N>、std::span<std::string>、标准库范围适配器等非单参数模板的range类型。
最简实现(C++20及以上)
首先定义一个通用的「元素为指定类型的range」concept:
#include <ranges> #include <string> template <typename Elem, std::ranges::input_range R> concept range_of = std::same_as<std::ranges::range_value_t<R>, Elem>;
之后你就可以直接写出接近预期的声明形式:
std::string concat(const range_of<std::string> auto& strings);
如果不需要复用这个concept,也可以直接把约束写在requires子句里:
std::string concat(const std::ranges::input_range auto& strings) requires std::same_as<std::ranges::range_value_t<decltype(strings)>, std::string>;
如果允许接收可隐式转换为string的元素范围,把上述代码中的std::same_as替换为std::convertible_to即可。
相关问题说明
你之前误以为这是标准的缺陷,实际上是对concept的使用场景存在误解:
- 你原本的写法是在约束模板模板的属性,而你的需求本质是约束具体类型的属性(任意range类型,只要元素是string),完全不需要用到模板模板参数。
- 如果你确实有约束模板模板参数的需求,C++20也支持模板模板参数的concept,只是你的场景不需要这种用法,不存在标准层面的缺陷。
内容的提问来源于stack exchange,提问作者Salvage
相关产品推荐
相关产品推荐

