簡體   English   中英

為什么我不能在std :: transform中使用std :: get <0>?

[英]Why can't I use std::get<0> in std::transform?

在嘗試編譯以下代碼時,會將map s鍵復制到vector

map<string, string> mss;
vector<string> vs;

transform(mss.begin(), mss.end(), back_inserter(vs), get<0>);

VS2013無法區分哪個get是有意的,但這個更簡單的用法可以正常工作:

vs.push_back(get<0>(*mss.begin()));

指定get<0, string, string>沒有幫助。 我錯過了什么?

std::get有很多重載,其中每個都是一個函數模板本身,因此編譯器無法在你請求其中一個地址的調用站點分辨出你想要的那個。 如果你堅持使用std::get ,你需要使用static_cast

transform(mss.begin(), mss.end(), back_inserter(vs),
          static_cast<const map<string, string>::key_type&
                         (*)(map<string, string>::value_type&)>(std::get<0>)
                     );

只要static_cast中的類型與作為參數給出的可能的函數模板的特化的聲明匹配,這將起作用。 此外,您不應嘗試顯式指定函數模板的模板參數,如get<0, string, string>等。這就是模板參數推導機制的用途。 語法不僅難看,而且將來可能會增加其他重載,從而破壞您的編譯。

一個更好的選擇是使用lambda表達式

transform(mss.begin(), mss.end(), back_inserter(vs),
          [](map<string, string>::value_type& p){ return p.first; });

一般的lambda表達式 (C ++ 14):

transform(mss.begin(), mss.end(), back_inserter(vs),
          [](auto& p){ return p.first; }); // or `return std::get<0>(p);`

或者std::mem_fn ,它將其參數綁定到指向數據成員或成員函數的給定指針:

#include <functional>

transform(mss.begin(), mss.end(), back_inserter(vs),
          mem_fn(&map<string, string>::value_type::first));

存儲在map中的對的第一個成員是const限定的。 所以技術上你需要

get<0, const string, string>

但是這並不會將候選列表限制為一個明確的重載,因為get至少有兩個版本:const參數參數和非const參考參數。

您可以使用演員表選擇一個

const string &(*g)(const pair<const string, string> &) = 
  get<0, const string, string>; 

要么

typedef map<string, string> Map;

const Map::key_type &(*g)(const Map::value_type &) = 
  get<0, const Map::key_type, Map::mapped_type>; 

然后呢

transform(mss.begin(), mss.end(), back_inserter(vs), g);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM