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