Как связать конструктор в С++?

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

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", чтобы реализовать это?

Ответ 1

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

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

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

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

В общем случае, boost lambda library имеет функтор 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));

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

Ответ 2

Я не знаю, есть ли более холодные способы Boost, но вы могли бы написать что-то вроде этого:

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

transform(src.begin(), src.end(), back_insert(dest), Builder()); 

Ответ 3

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

Для функции-члена требуется связать объект.

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

В вашем случае аргументы конструктора (значения int из src) должны перейти к (возможному) back_inserter, который вызывает не-default ctor, а не std:: transform. (EDIT: это справедливо только для использования без копирования-ctor)

Собственно, здесь вы хотите вызвать std:: copy:

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

Ответ 4

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

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

Ответ 5

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

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

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 для создания объектов. Однако это нормальная функция, а не конструктор, поэтому применяются все обычные правила для функций, особенно для копирования и перемещения объектов.