C ++ 11 auto и size_type - PullRequest
       13

C ++ 11 auto и size_type

8 голосов
/ 28 марта 2012

Учитывая следующее использование auto:

std::vector<int> v;
for (auto i = 0; i < v.size(); ++i) {
   ...
}

Было бы идеально для C ++ вывести i как std::vector<int>::size_type, но если он смотрит только на инициализатор для i,было бы увидеть целое число.Что такое выводимый тип i в этом случае?Это правильное использование auto?

Ответы [ 4 ]

20 голосов
/ 28 марта 2012

Используйте decltype вместо auto для объявления i.

for( decltype(v.size()) i = 0; i < v.size(); ++i ) {
  // ...
}

Еще лучше, используйте итераторы для итерации по вектору, как показывает ответ @ MarkB.

13 голосов
/ 28 марта 2012

Почему бы не решить вашу проблему с итераторами?Тогда проблема исчезнет:

std::vector<int> v;
for (auto i = v.begin(); i != v.end(); ++i) {
   ...
}

Если вы хотите выполнить итерации с использованием индексов, я бы, вероятно, просто явно прописал тип: Вы знаете, что это такое.auto в основном используется для неизвестных или трудно набираемых типов шаблонов.

7 голосов
/ 28 марта 2012

Ответ на ваш вопрос "Это правильное использование авто?"нет по причинам, объясненным в других ответах.Для конкретного случая циклического перемещения по содержимому контейнера вам, скорее всего, лучше использовать цикл for, основанный на диапазоне:

постоянный ссылочный доступ к элементам, i - это const int&:

std::vector<int> v;
for (const auto& i :  v ) {
   std::cout << i << "\n";
}

неконстантный эталонный доступ, i - int&:

std::vector<int> v;
for (auto& i :  v ) {
   ++i;
   std::cout << i << "\n";
}

значение доступа, i - int:

std::vector<int> v;
for (auto i :  v ) {
   ...
}

искоро.Это также работает для массивов в стиле C.

3 голосов
/ 28 марта 2012

auto получает тип исключительно из инициализатора.Никакое внимание не уделяется другим применениям, по крайней мере, не для определения типа переменной.Чтобы принять это во внимание, можно выбрать decltype:

for (decltype(v.size()) i = 0; i < v.size(); ++i)

или вы можете переписать цикл, чтобы вернуться назад:

for (auto i = v.size(); i-- != 0; )

или выможет быть в состоянии полностью избежать цикла for.

...