You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法在std::ranges::transform中直接使用std::get?

为什么直接用std::get在std::ranges::views::transform中编译失败?

你尝试用std::get<0, size_t, size_t>作为std::ranges::views::transform的参数提取pair的第一个元素,代码如下:

std::vector<std::pair<size_t, size_t>> vec { {1, 1}, {2, 7} ,{4, 5}};
for(auto&& x:vec | std::ranges::views::transform(std::get<0, size_t, size_t>)) do_somenthing(x);

但编译报错:

/home/bigbigbige/easytools/transform.cpp: In function ‘int main()’:
/home/bigbigbige/easytools/transform.cpp:52:53: error: no match for call to ‘(const std::ranges::views::_Transform) (<unresolved overloaded function type>)’
   52 |     for(auto&& x:vec | std::ranges::views::transform(std::get<0, size_t, size_t>)) std::cout << x << std::endl;
      |                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

核心原因:std::get的重载歧义

std::get是一个多重重载的模板函数,它不仅支持std::pair,还适配std::tuple、std::array等多种容器类型。当你写出std::get<0, size_t, size_t>时,编译器无法确定你要调用的是哪一个具体重载版本——存在多个符合模板参数的std::get实例,编译器无法将这个重载集转换为transform所需的单一可调用对象类型,最终导致匹配失败。

而你自定义的pair_projection模板函数不存在这个问题:它的模板参数明确绑定了std::pair类型,实例化后是唯一确定的函数,编译器能清晰识别其类型,因此可以正常传递给transform。

更简洁的解决方法

不需要自定义投影函数,有几种更直接的实现方式:

  1. 使用Lambda表达式(最通用)
    Lambda可以明确捕获std::get的调用上下文,消除重载歧义:
std::vector<std::pair<size_t, size_t>> vec { {1, 1}, {2, 7} ,{4, 5}};
for(auto&& x : vec | std::ranges::views::transform([](const auto& p) {
    return std::get<0>(p);
})) {
    do_somenthing(x);
}
  1. 使用std::views::keys(C++20专属)
    C++20标准库提供了std::views::keys视图,专门用于提取std::pair的第一个元素,代码更简洁:
#include <ranges>

std::vector<std::pair<size_t, size_t>> vec { {1, 1}, {2, 7} ,{4, 5}};
for(auto&& x : vec | std::views::keys) {
    do_somenthing(x);
}
  1. 强制类型转换明确重载
    通过强制类型转换指定std::get的具体重载版本,告诉编译器你要的是针对std::pair<size_t, size_t>的实例:
std::vector<std::pair<size_t, size_t>> vec { {1, 1}, {2, 7} ,{4, 5}};
using GetFirstFunc = const size_t&(*)(const std::pair<size_t, size_t>&);
for(auto&& x : vec | std::ranges::views::transform(
    static_cast<GetFirstFunc>(std::get<0>)
)) {
    do_somenthing(x);
}

内容的提问来源于stack exchange,提问作者葛盈泽

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 10:17:47