Присвоение вектора одного типа вектору другого типа - PullRequest
4 голосов
/ 14 апреля 2010

У меня есть класс "Событие". В связи с тем, как обрабатываются даты, нам нужно обернуть этот класс в класс «UIEvent», который содержит событие и дату события в другом формате.

Как лучше всего разрешить преобразование из Event в UIEvent и обратно? Я подумал, что лучше всего перегружать конструктор присваивания или копирования UIEvent для принятия событий (и наоборот).

Ответы [ 2 ]

14 голосов
/ 14 апреля 2010

Есть два простых варианта, которые я могу придумать.

Первым вариантом будет тот, который вы опишите: создайте конструктор, который принимает объект другого типа:

struct UIEvent
{
    UIEvent(const Event&);
};

и используйте std::copy для копирования элементов из вектора одного типа в вектор другого:

std::vector<Event> eventVector;
std::vector<UIEvent> uiEventVector;

std::copy(eventVector.begin(), eventVector.end(), 
          std::back_inserter(uiEventVector));

Второй вариант - написать функцию преобразования, не являющуюся членом:

UIEvent EventToUIEvent(const Event&);

и используйте std::transform:

std::transform(eventVector.begin(), eventVector.end(), 
               std::back_inserter(uiEventVector), &EventToUIEvent);

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

5 голосов
/ 14 апреля 2010

Если вы можете преобразовать Event в UIEvent (например, если UIEvent имеет конструктор, который принимает Event в качестве параметра), то следующее присваивает один вектор другому:

uievent_vector.reserve(event_vector.size());
uievent_vector.assign(event_vector.begin(), event_vector.end());

Естественно, если бы это преобразование работало, то все равно было бы неплохо.

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

struct to_uievent {
    UIEvent operator()(const Event& e) {
        // ...
    }
};

// ...
    std::transform(event_vector.begin(), event_vector.end(),
                   back_inserter(uievent_vector),
                   to_uievent());

Вы, конечно, можете добавить столько перегрузок, сколько пожелаете, operator()() в вышеуказанном функциональном объекте, чтобы вы могли использовать этот же функциональный объект для других преобразований.

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