2013-03-05 182 views
45

第一個問題:是否可以使用自動「強制」const_iterator? 例如:如何使用自動獲取const_iterator?

map<int> usa; 
//...init usa 
auto city_it = usa.find("New York"); 

我只是想查詢的不是改變任何事情由city_it指出,所以我想有city_it是​​。但通過使用auto,city_itmap::find()的返回類型相同,即map<int>::iterator。任何建議?

+0

你想要一個特定類型的變量沒有指定類型?對不起,在這種情況下不能輕易完成。 – 2013-03-05 20:20:57

+0

[如何使用自動變量選擇迭代器類型](http://stackoverflow.com/questions/9453383/how-to-select-iterator-type-using-auto-variable) – ks1322 2013-07-01 12:38:14

+0

也許'static_cast const& >(美國).find(「紐約」)'? – 2013-07-01 21:11:19

回答

31

很抱歉,但我只是覺得最好的建議是使用auto在所有,因爲您要執行(隱式有效)類型轉換auto是爲了推斷確切類型,這不是你想要的。

只要寫這樣說:

std::map<std::string, int>::const_iterator city_it = usa.find("New York"); 

由於正確地指出的MooingDuck,使用類型別名可以提高代碼的可讀性和可維護性:

typedef std::map<std::string, int> my_map; 
my_map::const_iterator city_it = usa.find("New York"); 
+0

相關:當我需要這樣的東西時,我幾乎總是'typedef'我的容器。 – 2013-03-05 20:21:51

+0

@MooingDuck:對。讓我補充一點。謝謝 – 2013-03-05 20:22:17

+5

或者,如果出於任何晦澀的理由,有人討厭typedef,仍然存在'decltype(usa.cbegin())it = ...'; – us2012 2013-03-05 20:25:16

1

我不是在一個位置,現在來測試這個權利,但我認爲它會做的伎倆:

auto city_it = const_cast< const map<int> & >(usa).find("New York"); 
+1

嗯,但是什麼使得這個解決方案比簡單地將'map :: const_iterator'指定爲類型更好?它不以任何方式更短或更可讀。 – us2012 2013-03-05 20:17:03

+3

@ us2012:從技術上講,OP沒有要求更短或更易讀,他使用'auto'請求'const_iterator',這正是這個允許的。 :P – 2013-03-05 20:22:44

12

這不是一個顯着與@ Jollymorphic的答案相比,不同的轉換爲const轉換爲const,但我認爲使用像這樣的實用程序單行函數很方便:

template<class T> T const& constant(T& v){ return v; } 

這使得更吸引眼球的轉換:

auto it = constant(usa).find("New York"); 
// other solutions for direct lengths comparision 
std::map<std::string, int>::const_iterator city_it = usa.find("New York"); 
auto city_it = const_cast<const std::map<std::string, int>&>(usa).find("New York"); 

嗯,我會說,更大並不總是更好。您當然可以根據自己的喜好選擇功能的名稱 - as_const或只是const_是可能的選擇。

+0

我在使用這個想法的時候使用了'make_const'。 – GManNickG 2013-03-05 21:56:49

+2

@GMan:對我來說,'make_x'意味着至少有一件* new *的*創造*不存在。這就是爲什麼我選擇了'as_const',它改變了對象的* view *。 – Xeo 2013-03-05 22:51:51

+0

夠公平的。 :) – GManNickG 2013-03-05 23:11:40

6

使用自動(既保持一個可變的美國和一個const美國)另一個變種

map<std::string, int> usa; 
//...init usa 
const auto &const_usa = usa; 
auto city_it = const_usa.find("New York"); 

如果您不需要的地圖是可變的,在所有的初始化後,還有一些其他的選擇。

你可以定義美國爲const,用一個函數調用初始化它:

const map<std::string, int> usa = init_usa(); 
auto city_it = usa.find("New York"); 

或使用lambda來初始化一個const地圖:

const auto usa = [&]()->const map<std::string, int> 
    { 
    map<std::string, int> usa; 
    //...init usa 
    return usa; 
    }(); 
auto city_it = usa.find("New York"); 
-2

您可以使用自動「跟蹤」一類型或 「推斷」 類型: // deduce auto city_it = usa.find("New York");

// track auto city_it = std::map<int>::const_iterator(usa.find("New York"));

另外,手錶是Herb Sutter的現代C++風格談話,涵蓋了大部分這些類型的扣減指導。 https://youtu.be/xnqTKD8uD64

+0

'auto city_it = {std :: map :: const_iterator} usa.find(「New York」);'是語法錯誤。你能重新解釋一下你的回答,並解釋一下你想說的話嗎? – 2015-09-11 01:40:33

+0

我修正了錯字 – 2015-09-16 20:52:52

+0

這還是一個錯誤,'map '不是一個類型。而你並沒有解釋「演繹」和「曲目」之間的區別是什麼。 – 2015-09-16 23:27:39

5

一個乾淨的解決方案是將常量參考否則修改地圖的工作:

const auto &const_usa = usa; 
auto city_it = const_usa.find("New York"); 

這將確保您不能修改const_usa,並使用const的迭代器。

1

由於C++ 17可以使用std::as_const這樣的:

#include <utility> 

// ... 

auto city_it = std::as_const(usa).find("New York"); 
相關問題