2015-11-21 3 views
0

Предположим, у меня есть вектор строки, который содержит имя, и теперь я хочу создать вектор класса Athlete из этих имен векторов. Так как я могу создать один без используя цикл?Создайте вектор объекта из другого вектора строки

Вот мой Athlete класс:

class Athlete{ 
public: 
    Athlete(string name, int number); 

private: 
    string name; 
    int number, time; 
}; 

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

vector<string> names; 
vector<Athlete> athletes; 

for(auto i = names.begin(); i != names.end(); i++) 
    athletes.push_back(Athlete(*i, i - names.begin() + 1)); 

Но теперь я хочу, чтобы создать вектор спортсменов без используя цикл. Сначала я думал, что буду использовать generate, но тогда объект функции не может ссылаться на имена векторов. Итак, какую функцию я должен использовать?

+3

Какая утечка. Почему не просто 'athletes.push_back (Athlete (* i, i - names.begin() + 1));'? Или 'emplace_back', что угодно. – LogicStuff

+0

Извините, вы правы. Я этого не заметил. Благодарю. – Henry

+0

Вы всегда можете ['std :: transform()'] (http://en.cppreference.com/w/cpp/algorithm/transform). –

ответ

1

Lambda функция

Тем не менее технически цикл, но несколько раз уродливее:

#include <iostream> 
#include <vector> 
#include <string> 
#include <iterator> 
#include <algorithm> 

using std::cout; 
using std::endl; 

class Athlete { 
public: 
    Athlete(std::string name, int number) {}; 

private: 
    std::string name; 
    int number, time; 
}; 

int main() 
{ 
    std::vector<std::string> names; 
    std::vector<Athlete> athletes; 

    std::transform(names.begin(), names.end(), std::back_inserter(athletes), 
     [&names](std::string const& name) 
     { 
      return Athlete(name, &name - &names.front() + 1); 
     }); 
} 

Range на основе цикл

Забавно, потому что цикл может быть:

for(auto const& name : names) 
    athletes.emplace_back(name, &name - &names.front() + 1); 

объект Function # 1

Но так как вы хотите класс функтора, это определение:

class StringToAthleteFunct 
{ 
    std::vector<std::string> const& names; 

public: 

    StringToAthleteFunct(std::vector<std::string> const& names) : 
    names(names) 
    { 
    } 

    Athlete operator()(std::string const& name) const 
    { 
     return Athlete(name, &name - &names.front() + 1); 
    } 
}; 

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

std::transform(names.begin(), names.end(), std::back_inserter(athletes), 
    StringToAthleteFunct(names)); 

Функция объекта # 2

Ac концов эта одна лучше:

class StringToAthleteFunct 
{ 
    int index; 

public: 
    StringToAthleteFunct() : index(0) { } 

    Athlete operator()(std::string const& name) 
    { 
     return Athlete(name, ++index); 
    } 
}; 

- не требует ссылки на источник вектора

+0

* более уродливый *, lol, действительно, но хорошо показать технику. –

+0

Спасибо, уродливый, но работает. Но я все еще думаю, что в любом случае можно использовать функтор. – Henry

+0

Вы хотите зайти слишком далеко в уродство. Это обзор обратного кода? LOL – LogicStuff