2016-08-27 5 views
1

Я пытаюсь создать подконтейнеры контейнера через контейнер < \ T> (InputIt First, InputIt Last). Например, у меня есть строка s1 = «AreYouOK». Ожидаемые выходыИнициализация последовательного контейнера C++ с использованием итератора

A 
Ar 
Are 
AreY 
AreYo 
AreYou 
AreYouO 

Вот мой код:

#include <vector> 
#include <string> 
#include <iostream> 

using std::vector; 
using std::string; 
using std::cout; 
using std::cin; 
using std::endl; 

int main() 
{ 
    string s1 = "AreYouOK"; 
    vector<string> v; 

    for (string::const_iterator iter = s1.begin(); 
      iter != s1.end()-1; ++iter) 
    { 
     string s(s1.begin(),iter); // no matching container 
     s += *iter; 
     v.push_back(s); 
    } 

    for (vector<string>::const_iterator iter = v.begin(); 
      iter != v.end(); ++iter) 
    { 
     cout << *iter <<endl; 
    } 

    return 0; 
} 

Я ожидаю комментируемой строке

string s(s1.begin(),iter); 

для создания подстроки s из строки s1 в диапазоне [s1.begin(), iter), так как iter является итератором s1. Однако мне сказали, что для инициализации нет соответствующего конструктора.

error: no matching constructor for initialization of 'string' 
(aka 'basic_string<char, char_traits<char>, allocator<char> >') 
string s(s1.begin(),iter); 
    ^~~~~~~~~~~~~~~~ 

Хотя

string s(s1.begin(),s1.begin+3); 

удалось создать подстроку.

Почему

string s(s1.begin(),iter); 

не работает?

Большое спасибо!

+0

's1.begin()' возвращает 'iterator', а' iter' - 'const_iterator'. Ни один из конструкторов не принимает пару (итератор, const_iterator). –

+0

Вы могли бы избежать этого, если бы использовали [std :: accumulate] (http://ideone.com/yaSA8m) – PaulMcKenzie

ответ

1

Если посмотреть here, например, вы можете увидеть, что полное сообщение об ошибке содержит

prog.cpp:19:33: error: no matching function for call to 'std::basic_string<char>::basic_string(std::basic_string<char>::iterator, std::basic_string<char>::const_iterator&)' 

, который говорит, что он думает, что ваш вызов конструктора, который принимает iterator и (ссылка) const_iterator. Нет такого конструктора. Поскольку s1 является неконстантным объектом, s1.begin() возвращает обычный итератор.

Существует много способов обойти это. Один из них, чтобы изменить цикл для

string::const_iterator b = s1.begin(); 
    for (string::const_iterator iter = b; 
      iter != s1.end()-1; ++iter) 
    { 
     string s(b,iter); 
     ... 

Здесь вы действительно использовать два константные итераторы (см here ваш ожидаемый результат).


Редактировать

Два отлично (и выше) альтернативы:

  1. Используйте cbegin, если вы C++ 11 включен (@rici)

  2. Используйте accumulate, как только вы доберетесь до этого алгоритма (@PaulMcKenzie)

+0

Не проще ли просто изменить его тоже 'string s (s1.cbegin(), iter); ' – rici

+0

@rici Это отличная точка, но она не помечена как C++ 11, поэтому IDK, если OP имеет это. Однако добавим это как комментарий. Благодарю. –

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