Есть ли объект функции для создания объектов в STL? - PullRequest
2 голосов
/ 13 июля 2009

Рассмотрим следующий класс:

class Person {
public:
    // I don't want any "char *" to be converted to Person implicitly!
    explicit Person( const char * name ) : name_(name) {};

private:
    std::string name_;
};

Также рассмотрим следующий массив данных char *:

char STUDENT_NAMES[][20] = {
    "Bart",
    "Liza",
    "Maggie"
};

Теперь я хочу создать std :: список Person в соответствии с этим массивом. Все, что я мог придумать, это использовать алгоритм std :: transform с рукописными функциональный объект:

struct CreatePerson : public std::unary_function<const char*,Person> {
    Person operator() (const char * name) const {
        return Person(name);
    };
};

// ...

std::list<Person> students;
std::transform(
    &STUDENT_NAMES[ 0 ],
    &(STUDENT_NAMES[ sizeof(STUDENT_NAMES)/sizeof(STUDENT_NAMES[0]) ]),
    front_inserter(students),
    CreatePerson() );
// ...

Есть ли более короткий и / или более понятный способ сделать это? Может быть, какой-то стандарт функциональные объекты или адаптеры?

Ответы [ 4 ]

5 голосов
/ 13 июля 2009

Вы можете использовать boost::lambda следующим образом:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/construct.hpp>
#include <string>
#include <iterator>
#include <algorithm>
#include <list>

struct person {
  explicit person(char const *name)
   :name(name) { }
private:
  std::string name;
};

int main() {
  char names[][20] = {
    "Michael", "litb"
  };

  std::list<person> v;
  std::transform(names, names + 2, std::front_inserter(v), 
    boost::lambda::constructor<person>());
}

Я не думаю, что есть такой способ со стандартной библиотекой C ++.

2 голосов
/ 13 июля 2009

Конструктор вашего класса - это функция преобразования. Вам не нужно преобразовывать: вы можете просто вставить. Взгляните на этот код здесь .

std::list<Person> ps( NAMES, NAMES+sizeof(NAMES)/sizeof(NAMES[0]) );

В противном случае для более короткого временного решения использовалась бы статическая заводская функция:

struct Person {
    static Person create( const char* name );
     ....
 };

 std::transform( NAMES, NAMES+sizeof(NAMES)/sizeof(NAMES[0], front_inserter( ps ),
   &Person::create );
0 голосов
/ 13 июля 2009

Ну, я просто напишу метод / функцию вроде:

convert(const char*[] names, std::list<Person>&);

Почему бы и нет, если просто сделать простое преобразование? Может быть, я упускаю суть?

M2C

0 голосов
/ 13 июля 2009

Не очень помогает, но нет стандартного макроса ELEMENTS для

   sizeof(STUDENT_NAMES)/sizeof(STUDENT_NAMES[0])

Быстрый поиск не нашел, но я чувствую, что у каждой реализации, которую я использовал, есть.

Единственное другое предложение, которое у меня есть, - превратить CreatePerson в шаблон - таким образом, если вам это понадобится снова, вам просто нужно создать CreateObj или что-то в этом роде.

...