Как скопировать один вектор в другой, если у них разные типы? С++
При условии, что MyType2 может быть построен из MyType1, как мне инициализировать второй вектор? Пробовал сделать так:
std::vector vec2 ;
Отслеживать
задан 27 ноя 2021 в 7:41
ComeInRage ComeInRage
1,590 6 6 серебряных знаков 14 14 бронзовых знаков
а не получится ли «каша » с неизвестным состояний объектов.
27 ноя 2021 в 10:13
@ARHovsepyan ну у вас получается каша, если вы используете конструктор, принимающий в качестве аргумента другой класс?)
27 ноя 2021 в 11:10
это не одно и то же
27 ноя 2021 в 12:33
3 ответа 3
Сортировка: Сброс на вариант по умолчанию
assign работает хорошо, если есть подходящее преобразование, которым компилятор может воспользоваться. Если же у него это не получается, то можно сделать вот так
std::vector a ; std::vector b; std::transform( a.begin(), a.end(), // исходный вектор std::back_inserter(b), // результирующий вектор [](auto q) < return std::to_string(q) + "\n";>// функция преобразования );
я использовал back_inserter , который в данном случае просто скрывает push_back , но можно выделить память под результирующий вектор (через b.resize(a.size()); ) и потом можно просто указать b.begin()
Как скопировать один вектор в другой c
Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009
Репутация: нет
Всего: нет
Простите если было, поиском не нашел.
Как половчее скопировать часть одного вектора, допустим элементы с 10-го по 20-й в новый вектор?
Цикл не предлагать
| Дата 24.6.2011, 13:28 (ссылка) | (нет голосов) Загрузка . |
Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения
Репутация: 52
Всего: 211
| Дата 24.6.2011, 13:29 (ссылка) | (нет голосов) Загрузка . |
Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009
Репутация: нет
Всего: нет
| Цитата(azesmcar @ 24.6.2011, 13:28 ) |
| std::copy |
затрудняюсь в выборе параметров, например беру итератор через begin, чтобы указать 10-й элемент, можно просто дописать +10 ?
Добавлено @ 13:42
вот так православно будет?:
| Код |
| std::vector src; . std::vector part( src.at( 10 ), src.at( 20 ) ); |
Это сообщение отредактировал(а) semibug — 24.6.2011, 13:42
| Дата 24.6.2011, 13:45 (ссылка) | (нет голосов) Загрузка . |
Профиль
Группа: Участник
Сообщений: 515
Регистрация: 18.8.2006
Репутация: 2
Всего: 12
| Код |
| std::vector part( src.begin()+10, src.begin()+20 ); |
Итераторы же
| Дата 24.6.2011, 13:49 (ссылка) | (нет голосов) Загрузка . |
Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009
Репутация: нет
Всего: нет
ну точно, src.at( 10 ), src.at( 20 ) трактуется как два числа, соответственно получаем массив из 10-ти элементов со значением 20, значит буду отталкиваться от begin. Не пользовался раньше итераторами, не был уверен, что можно операцией сложения смещать его.
Спасибо!
| Дата 24.6.2011, 13:51 (ссылка) | (нет голосов) Загрузка . |
Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону
Репутация: 21
Всего: 135
| Цитата(semibug @ 24.6.2011, 13:49 ) |
| соответственно получаем массив из 10-ти элементов со значением 20 |
получаем массив из src[10] элементов, проинициализированных значением src[20]
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
| Дата 24.6.2011, 13:52 (ссылка) | (нет голосов) Загрузка . |
Профиль
Группа: Участник
Сообщений: 515
Регистрация: 18.8.2006
Репутация: 2
Всего: 12
| Цитата(semibug @ 24.6.2011, 13:49 ) |
| Не пользовался раньше итераторами, не был уверен, что можно операцией сложения смещать его. |
Вот матчасть по этому вопросу http://www.cplusplus.com/reference/std/iterator/
| Дата 24.6.2011, 14:58 (ссылка) | (нет голосов) Загрузка . |
Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения
Репутация: 52
Всего: 211
| Цитата(semibug @ 24.6.2011, 13:29 ) |
| затрудняюсь в выборе параметров, например беру итератор через begin, чтобы указать 10-й элемент, можно просто дописать +10 ? |
| Код |
| std::copy(vec.begin() + 10, vec.end(), std::back_inserter(another_vec)); |
как- то так.
| Дата 24.6.2011, 15:47 (ссылка) | (нет голосов) Загрузка . |
Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009
Репутация: нет
Всего: нет
| Цитата(borisbn @ 24.6.2011, 13:51 ) |
| получаем массив из src[10] элементов, проинициализированных значением src[20] |
верно, поспешил с выводом (набросал примерчик, где инициализировал исходный вектор циклом, значения и индексы совпадали, не подумав ляпнул)
Усе понятно, вопрос закрыт.
thx2all!
| Дата 24.6.2011, 19:37 (ссылка) | (нет голосов) Загрузка . |
Профиль
Группа: Участник
Сообщений: 127
Регистрация: 24.6.2011
Репутация: 1
Всего: 1
| Цитата(semibug @ 24.6.2011, 13:27 ) |
| Простите если было, поиском не нашел. Как половчее скопировать часть одного вектора, допустим элементы с 10-го по 20-й в новый вектор? Цикл не предлагать |
Как уже здесь было сказано, можно использовать для этих целей стандартный алгоритм std::copy.
Я бы хотел сделать некоторые замечания. Если хотите, чтобы ваш код был бы более переносимым, то не используйте операцию сложения итератора с целым числом. Это верно только для итераторов произвольного доступа. Лучше использовать функцию std::advance. Для итераторов произвольного доступа она инстанциируется в простое сложение итератора с целым числом. Но зато если вы захотите поменять контейнер, например, с вектора на список, то алгоритм с std::advance будет по-прежнему работать в отличии от использования сложения итератора с целым числом.
Пример выражения для алгоритма copy
std::copy( std::advance( v.begin(), 9 ), std::advance( v.begin(), 19 ), std::back_inserter( OtherVector) );
Кроме того, не ясно, куда именно во второй вектор или контейнер вы хотите скопировать элементы: либо в начало контейнера, либо в конец, либо вы хотите переписать элементы второго контейнера, либо вставить во второй контейнер элементы первого контейнера. От этого будет зависеть тип третьего операнда. Я показал пример, когда новые элементы будут добавляться в конец второго контейнера.
В-третьих, не бойтесь писать собственные алгоритмы, так как стандартные алгоритмы крайне ограничены и их система не полная. Например, по вине Страуструпа был исключен алгоритм copy_if, о чем теперь сам Страуструп очень жалеет.
Я, например, когда мне известно число элементов, которые нужно скопировать, использую собственный алгоритм copy_n. Его объявление следующее
template typename OutputIterator,
typename Size>
OutputIterator copy_n( ForwardIterator first, OutputIterator result, Size n );
Он напоминает фуекцию для строк strncpy.
6.3. Копирование вектора
Требуется скопировать содержимое одного vector в другой.
Имеется пара способов сделать это. Можно при создании vector использовать конструктор копирования, а можно использовать метод assign. Пример 6.3 показывает оба этих способа.
Пример 6.3. Копирование содержимого vector
using namespace std;
// Вспомогательная функция для печати содержимого вектора
void vecPrint (const vector& vec)
for (typename vector::const_iterator p = vec.begin();
vec2.assign(vec.begin(), vec.end()); // Копирование каждого элемента
vecPrint(vec2); // с помощью присвоения
vec2.assign(&foo[0], &foo[5]); // Присвоение работает для всего, что
vecPrint(vec2); // ведет себя как итератор
p = find(vec.begin(), vec.end(), «new»);
vec2.assign(vec.begin(), p); // Копирование подмножества полного диапазона
Копирование vector просто. Имеется два способа сделать это. Можно скопировать один vector в другой с помощью конструктора копирования, как и любой другой объект, а можно использовать метод assign. О конструкторе копирования сказать почти нечего. Просто передайте в него vector, который требуется скопировать, и все.
В этом случае vec2 будет содержать такое же число элементов, что и vec, и каждый из этих элементов будет копией элемента vec с таким же индексом. Каждый элемент копируется с помощью конструктора копирования string. Так как здесь используется конструктор, буфер vec2 имеет размер, достаточный для хранения всего, что есть в vec.
assign работает аналогично, за исключением того, что за кулисами выполняется дополнительная работа, связанная с тем, что теперь дело касается целевого vector который уже может содержать данные. Во-первых, требуется удалить элементы, которые оказались, так сказать, под ногами. Вначале assign для каждого из объектов, уже содержащихся в vec2, вызывает деструктор. После этого он проверяет размер буфера vec2, чтобы убедиться, что он достаточно большой, чтобы вместить то, что находится в vec. Если он не достаточен, assign изменяет размер буфера под размещение новых данных. Наконец, он копирует каждый элемент.
Кроме того, assign можно использовать для копирования подмножества последовательности. Например, если требуется скопировать подмножество элементов vec, просто укажите при вызове assign необходимый диапазон.
p = std::find(vec.begin(), vec.end(), «new»);
В этом случае assign скопирует все до, но не включая, p. Причиной этого является соглашение, по которому во всех контейнерах и алгоритмах стандартной библиотеки assign(first, last) копирует элементы, на которые указывает first, до, но не включая, элемент, на который указывает last. Такой диапазон, который включает первый элемент, но не включает последний, часто обозначается как (first, last).
Используйте assign или конструктор копирования вместо самостоятельного циклического перебора. Это значит, не копируйте каждый элемент, перебирая vec и помещая элементы в конец vec2 в цикле. Это потребует от вас большой избыточности кода и отключит все оптимизации, которые могут присутствовать в реализации assign и конструктора копирования стандартной библиотеки.
Читайте также
13.5.1. Копирование
13.5.1. Копирование Самый простой вариант создания резервной копии — использование команды cp (копирование файлов). Только в этом случае необходимо обязательно сохранять права доступа к файлу. Вот как может выглядеть команда, дублирующая директорию /home на примонтированном
8.4.1 Протоколы вектора расстояния
8.4.1 Протоколы вектора расстояния Самый простой протокол для сравнения маршрутизаторов использует счет попаданий между конечными точками пути. Некоторые улучшенные варианты оценивают стоимость или вес каждого из участков по пути следования. Например, участок попадания
Копирование
Копирование Вставьте компакт-диск в привод. Щелкните мышью на кнопке Копировать с диска (рис. 3.22). С помощью соответствующих флажков отметьте произведения, предназначенные для копирования. В строке состояния при этом будет отображаться количество выбранных
11.8. Представление динамического числового вектора
11.8. Представление динамического числового вектора ПроблемаТребуется иметь тип для манипулирования динамическими числовыми векторами.РешениеВы можете использовать шаблон valarray из заголовочного файла <valarray>. Пример 11.15 показывает, как можно использовать шаблон
11.9. Представление числового вектора фиксированного размера
11.9. Представление числового вектора фиксированного размера ПроблемаТребуется иметь эффективное представление числовых векторов фиксированного размера.РешениеВ программном обеспечении обычного типа часто более эффектный результат по сравнению с valarray дает
11.11. Вычисление нормы вектора
11.11. Вычисление нормы вектора ПроблемаТребуется найти норму (т. е. длину) числового вектора.РешениеМожно использовать функцию inner_product из заголовочного файла <numeric> для умножения вектора на самого себя, как показано в примере 11.21.Пример 11.21. Вычисление нормы вектора#include
Копирование
Копирование В этом примере мы копируем базу данных, находящуюся на диске D: удаленного сервера, в файл копии на диске F: той же самой удаленной машины. Мы направляем подробный отчет об операции в файл протокола в другом каталоге. Как обычно, пример является одной строкой:gbak
Копирование
Копирование BlindWrite Suite Сайт: http://www.blindwrite.comРазмер: 2,8 МбСтатус: SharewareЦена: $32Весьма популярная на Западе программа для точного копирования дисков. Ранее поставлялась в виде двух отдельных модулей – BlindRead, отвечавшего за сброс содержимого диска в файл-образ и собственно
1.11 Вектора
1.11 Вектора Встроенное в С++ понятие вектора было разработано так, чтобы обеспечить максимальную эффективность выполнения при минимальном расходе памяти. Оно также (особенно когда используется совместно с указателями) является весьма универсальным инструментом для
1.17 Полиморфные Вектора
1.17 Полиморфные Вектора У вас есть другая возможность – определить ваш векторный и другие вмещающие классы через указатели на объекты некоторого класса: class common (* //. *); class vector (* common** v; //. public: cvector(int); common* amp; elem(int); common* amp; operator[](int); //. *);Заметьте, что поскольку в таких
2.3.7 Указатели и Вектора
2.3.7 Указатели и Вектора Указатели и вектора в С++ связаны очень тесно. Имя вектора можно использовать как указатель на его первый элемент, поэтому пример с алфавитом можно было написать так:char alpha[] = «abcdefghijklmnopqrstuvwxyz»; char* p = alpha; char ch;while (ch = *p++) cout «„ chr(ch) „« » = » «« ch «« « = 0“ ««
5.5.5 Вектора Объектов Класса
5.5.5 Вектора Объектов Класса Чтобы описать вектор объектов класса, имеющего конструтор, этот класс должен иметь конструктор, который может вызваться без списка параметров. Нельзя использовать даже парметры по умолчанию. Например:table tblvec[10];будет ошибкой, так как для
Вектора, допускающие сложение
Вектора, допускающие сложение Приведем простой, но характерный пример, демонстрирующий необходимость введения ограниченной универсальности. Он поможет в обосновании метода решения поставленной задачи и в выборе соответствующей конструкции языка.Предположим, что мы
передать вектор в C++11

Что сказать-то хотел? Предлагаю обсудить релевантые 21 веку языки, где вместо арсенала для стрельбы в ногу ‘should be one— and preferably only one —obvious way to do it’.
t184256 ★★★★★
( 07.04.16 13:30:00 MSK )

std::vector f()
Dudraug ★★★★★
( 07.04.16 13:53:53 MSK )
Последнее исправление: Dudraug 07.04.16 13:54:56 MSK (всего исправлений: 2)

std::vector x(5);
(5) здесь не нужно
std::vector f()
Ты же понимаешь, да, что второй вызов этой функции к такому же результату не приведёт?
intelfx ★★★★★
( 07.04.16 14:00:28 MSK )

Давайте устроим конкурс на самую неочевидную строчку кода!
Dudraug ★★★★★
( 07.04.16 14:04:45 MSK )
Ответ на: комментарий от Dudraug 07.04.16 14:04:45 MSK
а что в этой строчке неочевидного?
anonymous
( 07.04.16 14:10:29 MSK )
Ответ на: комментарий от anonymous 07.04.16 14:10:29 MSK

К тому что в текущем конкретом примере такая конструкция избыточна. Да и не очевидна она. Да, я знаю, что подобны пример есть в оф доке
Но более очевидным такой код не становится, от того что ты уже знаешь как оно работает. Можно и на ассемблере писать и понимать, что написано, но код от на ассемблере от этого не станет более читабельным. Но это придирка скорее в целом к проектированию stl, чем к автору.
Dudraug ★★★★★
( 07.04.16 14:28:10 MSK )
Ответ на: комментарий от anonymous 07.04.16 14:10:29 MSK

Просто вывод через copy, ну я даже не знаю=)