2013-11-26 2 views
2

данными строки s типа std::string Я строй другого строку s2 как такстроит строку с итераторами

std::string(s.begin(), s.begin() + s.find(" ")) 

но следующий конструктор не работает

std::string(s.begin(), s.find(" ")) 

кто-нибудь знает почему? Я использую g++ 4.8.1 under Ubuntu amd64

Оба конструктора имеют итератор в качестве второго аргумента.

В этом примере я пытаюсь создать строку, содержащую первую подстроку, которая заканчивается там, где появляется первый пробел.

ответ

2

std::string::find() возвращает смещение, а не итератор (да, это во многом несоответствие конструкции стандартной библиотеки). Таким образом, чтобы использовать это (и включают в себя надлежащую проверку ошибок), сделать что-то вроде этого:

size_t offset = s.find(" "); 
std::string(s.begin(), (offset == std::string::npos ? s.end() : s.begin() + offset); 
+0

О, спасибо, я не знаю, почему я действительно был убежден в том, чтобы иметь дело с итератором, я предполагаю, что после многого с потоками и 'char' вы ожидаете чего-то подобного ... – user2485710

+1

@ user2485710: Возможно, вы думали об алгоритме ['std :: find()'] (http://en.cppreference.com/w/cpp/algorithm/find), который возвращает итератор? – Johnsyweb

+0

, скорее всего, да, но до сих пор не может понять, почему существует такой подход для пространства имен 'string ::'. В любом случае, спасибо. – user2485710

1

Потому что find возвращает индекс (size_type). Поскольку строка является непрерывным контейнером, s.begin() + s.find(" ") вернет вам итератор, поскольку он эквивалентен вызову std::string::iterator operator+=(std::string::size_type s). Второй, конечно, будет ошибкой компиляции.

+0

- это самый эффективный способ получения такого подстроки? – user2485710

+0

Любой способ получения подстроки будет примерно одинаковой производительности: все они будут «O (n)», то есть. – Yuushi

+0

ok, я думал о методе, который работает предикатом, и возвращает копию подстроки, соответствующей этому предикату, но я ожидал что-то вроде O (n). Благодарю. – user2485710

1

Возможно, вы подумывали об алгоритме std::find(), который возвращает итератор?

#include <iostream> 
#include <algorithm> 

int main() 
{ 
    std::string s = "Derek Smalls"; 
    std::string s2(std::begin(s), std::find(std::begin(s), std::end(s), ' ')); 
    std::cout << s2 << std::endl; 
} 

See it run!

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