2014-10-11 2 views
6

Есть ли способ синтаксически сократить/упростить декларации итератора на C++. Обычно, я бы:Простой экземпляр итератора ST ++ STL

vector<pair<string, int> > v; 
vector<pair<string, int> >::iterator i; 

Я надеялся на какой-то магии, которая бы:

vector<pair<string, int> > v; 
magic v::iterator i; 
+0

Если вы используете C++ 11, проверьте спецификатор 'auto'. – Macmade

+1

Если вы используете C++ 11, просто скажите 'auto i (v.begin());' и компилятор выведет правильный тип для 'i'. http://en.cppreference.com/w/cpp/language/auto – dgnuff

ответ

5

В C++ 11, у вас есть три возможности:

1. Typedef векторный экземпляр

typedef std::vector<std::pair<std::string, int>> Vp; 
Vp v; 
Vp::iterator i; 

2. Использование decltype

std::vector<std::pair<std::string, int>> v; 
decltype(v)::iterator i; 

3. Использование auto

std::vector<std::pair<std::string, int>> v; 
auto i = v.begin(); 

Я бы сказал, что третий вариант является наиболее распространенным, идиоматическое использование, но все valid, а первый вариант работает и на C++ 98.

+0

Сложность - это волшебство, которое я искал. Жаль только в C++ 11. – Waslap

7

Просто использовать typedef для наложения ваших vector<pair<string, int> >

typedef vector<pair<string, int> > Vp; // vector of pair 

А потом,

Vp v; 

Vp::iterator i; 
0

C++ 11:

using v = vector<pair<string, int> >; 
using i = v::iterator; 

Magic:

v _v; 
i _i{ _v.begin() }; 
2

Я использую определение типов много:

// vector of strings 
typedef std::vector<std::string> str_vec; 

// iterator 
typedef str_vec::iterator str_vec_iter; 

// constant iterator 
typedef str_vec::const_iterator str_vec_citer; 

// reverse iterator 
typedef str_vec::reverse_iterator str_vec_riter; 

// constant reverse iterator 
typedef str_vec::const_reverse_iterator str_vec_criter 

int main() 
{ 
    str_vec v = {"a", "b", "c"}; 

    // writable iteration 
    for(str_vec_iter i = v.begin(); i != v.end(); ++i) 
     i->append("!"); 

    // constant iteration 
    for(str_vec_citer i = v.begin(); i != v.end(); ++i) 
     std::cout << *i << '\n'; 

    // constant reverse iteration 
    for(str_vec_criter i = v.rbegin(); i != v.rend(); ++i) 
     std::cout << *i << '\n'; 
} 

Некоторых контейнеры являются настолько распространенными, что у меня есть свои определения типов в личные файлы заголовков, которые я использую все время (имена, естественно,).

Но так как C++ 11 его не так важно, из-за auto ключевое слово, которое выводит тип для вас:

for(auto&& i: v) 
    std::cout << i << '\n'; 
2

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

decltype(v)::iterator 
Смежные вопросы