Как связать конструктор в C ++? - PullRequest
12 голосов
/ 29 ноября 2010

Излишне объяснять. Следующий код самоочевиден:

struct X
{
    X(int n){}
};

int main()
{
    std::vector<int> src;
    std::vector<X>   dest;

    // Below is not valid in current C++, but that is just what I want.
    transform(src.begin(), src.end(), back_insert(dest), std::bind(&X::X, _1)); 
}

Конструктор принимает некоторые аргументы и возвращает объект класса конструктора.

Конструктор выглядит как функция, действует как функция и является в точности функцией.

Итак, я думаю, что std :: bind должен одинаково обрабатывать конструкторы и другие вызываемые объекты.

Однако, как я могу расширить шаблон функции "bind", чтобы реализовать это?

Ответы [ 5 ]

15 голосов
/ 29 ноября 2010

Так как X неявно конструируется из int, простая копия должна выполнить преобразование.

copy(src.begin(), src.end(), std::back_inserter(dest)); 

Или даже используя конструктор вектора:

std::vector<X>   dest(src.begin(), src.end());

ВВ общем случае в лямбда-библиотеке boost есть функтор constructor.

#include <boost/lambda/bind.hpp>
#include <boost/lambda/construct.hpp>
...
using namespace boost::lambda;
transform(src.begin(), src.end(), std::back_inserter(dest), bind(constructor<X>(), _1));

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

6 голосов
/ 29 ноября 2010

Я не знаю, есть ли кулер Методы повышения, но вы могли бы написать что-то вроде этого:

class Builder
{
    X operator() (int value) const { return X(value); }
};

transform(src.begin(), src.end(), back_insert(dest), Builder()); 
3 голосов
/ 29 ноября 2010

Конструктор является функцией-членом.

Функция-член нуждается в привязке к объекту.

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

В вашем случае аргументы конструктора (значения int из src) должны идти (возможно) в back_inserter, который вызывает не-по умолчанию ctor, а не в std:: преобразование.(РЕДАКТИРОВАТЬ: это верно только для использования без копирования ctor)

На самом деле, здесь вы хотите вызвать std :: copy:

std::copy(src.begin(), src.end(), std::back_inserter(dest)); 
1 голос
/ 29 ноября 2010

Конструктор принимает некоторые аргументы и возвращает объект класса конструктора.

Нет, конструктор ничего не возвращает, и нет такой вещи как указательконструктор.

0 голосов
/ 06 февраля 2014

Построить заводскую функцию. Это статические функции-члены или автономные функции, которые также создают объекты, обычно после проверки входных данных. Они полезны всякий раз, когда вы хотите убедиться, что ваши объекты не могут быть построены с неверным вводом (в конце концов, вы не можете прервать построение внутри ctor).

Поскольку фабрика - это обычная функция, вы можете легко связать ее, чтобы получить тот же эффект, который вам нужен - связанную функцию, которая создает объекты.

class X
{
public:
   X(OtherObject a, OtherData data);
   virtual ~X() {}
};

// Factory- return "X" instead of "X*" if not using the heap
X* CreateX(OtherObject a, OtherData data) {
    /*
        Logic that checks a, data for validity...
    */
    if(invalid) {
       return 0;   // You get no object
    }
    return new X();
}

Теперь вы просто привязываетесь к «CreateX» для создания объектов. Однако это обычная функция, а не конструктор, поэтому применяются все нормальные правила для функций, особенно правила копирования и перемещения объектов.

...