2015-09-19 3 views
4

Я хочу скопировать std::vector<int> в другой std::vector<myStruct> с оператором присваивания, в котором myStruct может быть назначен int. Так что я написал этот кусок кода:автоматическое преобразование между векторами stl

#include <vector> 
#include <iostream> 

using namespace std; 

struct myStruct 
{ 
    myStruct(int& a) : _val(a) { } 
    myStruct(int&& a) : _val(a) { } 

    myStruct& operator=(int& a) 
    { 
     _val = a; 
     return *this; 
    } 

    int _val; 
}; 

int main() 
{ 
    vector<int> ivec; 
    ivec.push_back(1); 
    vector<myStruct> svec = ivec; 

    return 0; 
} 

И это дает мне ошибку, поскольку он не может найти действительное преобразование между std::vector<myStruct> и std::vector<int> хотя int неявно могут быть преобразованы в myStruct. С другой стороны, присваивать оператор нельзя объявить вне класса, поэтому я выводю, что запись оператора вручную не является вариантом. Так что я должен делать в этой ситуации?

*** UPDATE: Как Blastfurnace и другие сказали, это может быть решена с помощью этого кода вместо присваивания:

vector<myStruct> svec(ivec.begin(), ivec.end()); 

Но представьте себе ситуацию, в которой я хочу написать библиотеку и хотите, чтобы справиться с этим в самой библиотеке, так что пользователь может просто написать std::vector<myStruct> svec = someFunction(), в котором someFunction возвращает std::vector<int>. Разве нет решения для этого?

+1

Вы можете использовать 'vector svec (ivec.begin(), ivec.end());' вместо этого. – Rostislav

+0

@Rostislav: Отправьте это как ответ, я отправил то же самое через несколько секунд после вас. – Blastfurnace

+0

@Blastfurnace Спасибо :) Я также добавил дополнительную информацию. Благодаря! – Rostislav

ответ

1

Ваш лучший выбор с функцией преобразования

std::vector< myStruct> convertVector(const std::vector< int> & other) 
{ 
    return std::vector< myStruct> (ivec.begin(), ivec.end()); 
} 

, которая бы автоматически использовать оптимизацию возвращаемое значение, так никаких накладных расходов для копирования данных в два раза (вы просто скопировать данные один раз вместо того, чтобы, когда вы перебирать «другой» вектор).


Просто для полноты картины:

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

class IntVector: public std::vector<int>{ 
    public: 
    //conversion operator (note a VERY BAD IDEA using this, may come in handy in few cases) 
    operator myStructVector() { 
     return convertVector(*this); 
    } 
} 

class myStructVector: public std::vector< myStruct>{ 
    //.... 
}; 

использование:

int main() 
{ 
    IntVector ivec; 
    ivec.push_back(1); 
    myStructVector svec = (myStructVector)ivec; 

    return 0; 
} 

В любом случае я бы отказался от этого пути ^^

+1

Угадайте, тогда нет способа, я выберу ваш ответ, поскольку у него будет больше информации;) – Sinapse

5

Вы можете использовать перегрузку конструктора, который принимает диапазон итератора:

vector<myStruct> svec(ivec.begin(), ivec.end()); 
+0

Я уверен, что это сработает, но представьте себе ситуацию, в которой я хочу написать библиотеку и хочу ее обработать в самой библиотеке, поэтому пользователь может просто написать 'std :: vector svec = someFunction()', в котором someFunction возвращает 'std :: vector '. Разве нет решения для этого? – Sinapse

+0

@ Синапс: Я не думаю, что это возможно, но кто-то с большим мозгом, чем я могу придумать окончательный ответ. – Blastfurnace

+0

Спасибо, я скажу пользователям, чтобы получить такой вектор, если я не нашел ничего хорошего;) – Sinapse

4

Вы можете использовать vector<myStruct> svec(ivec.begin(), ivec.end()); вместо этого.

Вы также можете использовать std::copy(ivec.begin(), ivec.end(), std::back_inserter(svec)); или svec.assign(ivec.begin(), ivec.end());, как это могло бы быть лучше, если вы назначаете несколько раз, как он может повторно использовать емкость vector<myStruct> после того, как был очищен.

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