2010-08-08 3 views
21

Я видел код, который использует вектор,Используйте автоматическое ключевое слово в STL C++

vector<int>s; 
s.push_back(11); 
s.push_back(22); 
s.push_back(33); 
s.push_back(55); 
for (vector<int>::iterator it = s.begin(); it!=s.end(); it++) { 
    cout << *it << endl; 
} 

Это так же, как

for (auto it = s.begin(); it != s.end(); it++) { 
    cout << *it << endl; 
} 

Насколько безопасен в этом случае использование авто ключевого слова? А что, если тип вектора float? string?

ответ

38

Ключевое слово auto просто просит компилятор вывести тип переменной из инициализации.

Даже компилятор pre-C++ 0x знает, что такое тип выражения (инициализации), и чаще всего вы можете видеть этот тип сообщений об ошибках.

#include <vector> 
#include <iostream> 
using namespace std; 

int main() 
{ 
    vector<int>s; 
    s.push_back(11); 
    s.push_back(22); 
    s.push_back(33); 
    s.push_back(55); 
    for (int it=s.begin();it!=s.end();it++){ 
     cout<<*it<<endl; 
    } 
} 

Line 12: error: cannot convert '__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<int*, __gnu_norm::vector<int, std::allocator<int> > >, __gnu_debug_def::vector<int, std::allocator<int> > >' to 'int' in initialization 

авто ключевое слово просто позволяет вам воспользоваться преимуществами этого знания - если вы (составитель) знать правильный тип, просто выбрать для меня!

+0

Я использую visual C++ 2010, поэтому у моего компилятора нет проблем с авто ключевым словом –

+0

Хорошее объяснение. +1 – jalf

+3

Мне особенно нравится, что 'auto' является * heluvalot * короче фактического типа. –

11

Ключевое слово auto получает тип из выражения справа от =. Поэтому он будет работать с любым типом, единственным требованием является инициализация автоматической переменной при ее объявлении, чтобы компилятор мог вывести этот тип.

Примеры:

auto a = 0.0f; // a is float 
auto b = std::vector<int>(); // b is std::vector<int>() 

MyType foo() { return MyType(); } 

auto c = foo(); // c is MyType 
+10

Хотя технически корректно. Надеюсь, это станет плохой практикой. Если все просто объявят все свои переменные 'auto', людям будет трудно читать и понимать (и мы идем по дороге к нетипизированным языкам). Использование авто должно быть зарезервировано для ситуаций, когда мы действительно не заботимся о типе, если он ведет себя в усадьбе, которую мы хотим (например, итераторам, нам неинтересно, какой итератор мы получаем до тех пор, пока мы можем используйте его как итератор). –

+1

@Martin: Не шучу, в первый раз, когда я увидел блок «автоматических» переменных, которые, как я думал, «умрете быстро». Как вы сказали, он должен использоваться в таких «gimme переменная, независимо от типа», а не «объявлять переменную» и выводить ее тип из ее инициализатора hehehehe! » пытаясь быть хитрым дерьмом. – GManNickG

+0

@sverkerw: Нет. Я имею в виду, что людям трудно читать. Каков тип c? Мне нужно знать. Как это влияет на мою интерпретацию остальной части кода. –

3

auto ключевое слово предназначено для использования в такой ситуации, это абсолютно безопасно. Но, к сожалению, он доступен только в C++ 0x, поэтому у вас будут проблемы с переносимостью.

21

Это дополнительная информация и не является ответом. Но так как я не имею репутацию чего прийти комментарий, я могу только написать здесь:

В C++ 11 вы можете написать:

for (auto& it : s) { 
    cout << it << endl; 
} 

вместо

for (auto it = s.begin(); it != s.end(); it++) { 
    cout << *it << endl; 
} 

Он имеет то же значение.

Обновление: См. Комментарий @ Alnitak.

+12

они не эквивалентны - в первом переменная 'it' имеет тип' value_type' и на самом деле не является итератором. – Alnitak

+0

Я бы заменил 'std :: endl'' '\ n" 'в этом случае, предотвращая операцию сброса. [Мотивация] (https://stackoverflow.com/questions/213907/c-stdendl-vs-n) – JHBonarius

2

Это новый предмет на языке, который, как я думаю, мы будем бороться в течение долгих лет. «Авто» начала представляет собой не только проблему с читабельностью, отныне, когда вы сталкиваетесь с ней, вам придется потратить много времени, пытаясь выяснить, что это такое (так же, как время, когда стажер назвал все переменные xyz :)), но вы также потратите значительное время на уборку после легкомысленных программистов, как тот, кто ответил мне передо мной. Пример сверху, я могу пожертвовать $ 1000, будет написано «для (автоматически: s)», а не «для (auto & it: s)», в результате чего вы используете семантику перемещения, в которой вы ожидаете ее, изменяя коллекция внизу.

Другой пример проблемы - это ваш вопрос.Вы явно не знаете много о stl-итераторах и пытаетесь преодолеть этот пробел благодаря использованию магии «auto», в результате вы создаете код, который может быть проблематичным позже.

Смежные вопросы