STL Algo Библиотека копия () - PullRequest
       3

STL Algo Библиотека копия ()

1 голос
/ 29 января 2012

Просто вопрос о том, как работает копия ... Мне нужна проверка для целей психического здоровья. Если у меня есть:

multiset<pair<double, string> > myMultiset;

и я пытаюсь распечатать содержимое на консоль ... Я должен ожидать ошибку при использовании:

copy(myMultiset.begin(), myMultiset.end(), ostream_iterator</.../>(cout, " "));

Это потому, что для A. для ostream_iterator я пытаюсь передать тип "pair", который ostream не понравится? Если бы мультимножество было сделано из «пары», даже если бы я передавал только строку типа через «ostream», я чувствую, что попытка передать два элемента одновременно вызовет ошибку. есть ли итератор, который будет перебирать только ключи или только значения? Есть ли чистый способ справиться с этим? Каждый раз, когда я просто пишу циклы for (), я могу получить содержимое с помощью «iter-> first» и «iter-> second» ... Я новичок в STL Algo, но мне нравится идея чистоты, и я хотел бы использовать их возможности ... Хотя так много мелочей ...

Ответы [ 2 ]

4 голосов
/ 29 января 2012

Причина, по которой ваш std::copy() не будет работать как есть, заключается в том, что для std::pair не определено std::operator<<(). Есть много разумных способов, которыми пользователь мог бы текстуально отформатировать пару, и стандарт оставил это неопределенным. Вы можете определить один самостоятельно:

template<typename K, typename V>
std::ostream& operator<<(std::ostream& out, std::pair<K,V> const& p)
{
    return out << p.first;
}

// ...
std::copy(set.begin(), set.end(),
          std::ostream_iterator<double>(std::cout, " "));

или определите функцию и используйте std::transform() вместо:

std::transform(set.begin(), set.end(),
               std::ostream_iterator<double>(std::cout, " "),
               [](std::pair<double,std::string> const& p) {
    return p.first;
});

Может оказаться полезным извлечь лямбду-ключ и извлечь из нее вспомогательный функтор для повторного использования:

struct keys_of {
    template<typename K, typename V>
    K operator()(std::pair<K,V> const& p) const
    {
        return p.first;
    }
};

// ...
std::transform(set.begin(), set.end(),
               std::ostream_iterator<double>(std::cout, " "),
               keys_of());

Иногда цикл for делает более простым, лаконичным, более понятным. Новая основанная на диапазоне for петля делает это еще дальше:

for( auto p : set ) {
    std::cout << p.first << ' ';
}

Это будет немного отличаться от других подходов в том, что в конце он оставит ограничитель свободного пространства. Он также работает только с контейнером; если у вас есть пара итераторов, а не контейнер (скажем, пара std::istream_iterator или пара произвольных итераторов в контейнер), вам следует использовать алгоритм. Но я думаю, что это самое простое и понятное из всех.

1 голос
/ 29 января 2012

Вы используете C ++ 11?Если это так, вы можете использовать алгоритм transform с лямбда-кодом для извлечения ключа (или значения).

Вы можете делать подобные вещи в более старом C ++, но это немного запутанно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...