2012-03-27 5 views
8

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

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

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

+0

Не зная, что вы делаете с 'i', невозможно сказать. –

+0

Я никогда не знал, что 'auto' используется для вывода соответствующего типа переменной! Имеет ли это? –

+3

@ Mr.TAMER Да, они изменили свой смысл на C++ 11. –

ответ

20

Использовать decltype вместо auto, чтобы объявить i.

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

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

+3

Или даже лучше использовать диапазон для цикла, как в ответе ниже. – juanchopanza

13

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

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

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

+1

он должен начинаться (v) и заканчиваться (v) – Klaim

3

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

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

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

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

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

7

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

константной ссылки доступа к элементам, 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.