Есть две проблемы здесь, 1. То, как решить то, что печатает каждого ребенка, будет, и 2. Как создать многократных детей.
Решить который ребенок создать
Это может быть сделано во время компиляции или время выполнения. Чтобы сделать это во время компиляции, вам нужны шаблоны.
template
vector> CreateVec(Arg1&& arg1, Arg2&& arg2)
{
vector> result;
result.push_back(unique_ptr(
new Child(std::forward(arg1), std::forward(arg2))));
return result;
}
called as follows CreateVec(myArg1, myArg2)
.
Если необходимо решить во времени выполнения, можно использовать карту фабричных функций, внесенных в указатель динамической переменной. Или вы могли использовать указатель на объект фабрики как ваша динамическая переменная.
Создать многократных детей
Здесь у вас есть выбор между цепочечными функциями и variadic шаблонами.
Цепочечные функции
Это по существу, что делает iostreams. Имейте свою функцию, которая создает вектор и добавляет, что холостой ребенок возвращает объект, который позволяет вам добавлять второго ребенка и возвращает себя разрешающий вам продолжиться.
Проблема здесь состоит в том, что вы хотите, чтобы функция возвратила вектор, таким образом, это не может также возвратить другой объект. Вы могли использовать оператор преобразования, чтобы получить вектор, или явная функция, но вероятно самый легкий должна создать вектор сначала, и просто использовать функции, чтобы добавить детей.
class AddChildren
{
vector>& m_vector;
public:
explicit AddChildren(vector>& theVector)
: m_vector(theVector) {}
template
AddChildren& add(Arg1&& arg1, Arg2&& arg2)
{
m_vector.push_back(unique_ptr(
new Child(std::forward(arg1), std::forward(arg2))));
return *this;
}
};
используемый следующим образом:
vector> myvector;
AddChildren(myvector)
.add(var1, var2)
.add(var3, var4)
.add(var5, var6);
При использовании метод во время выполнения выбора типа, можно использовать оператора()
и имеют его, похожи на это:
vector> myvector;
AddChildren(myvector)
(childAType, var1, var2)(childBType, var3, var4)(childCType, var5, var6);
(Это может также быть сделано с выбором времени компиляции типа при помощи фиктивного объекта типа отборщика определенного типа для каждого детского типа в качестве параметра.)
Используя variadic шаблоны
Используйте variadic шаблон, чтобы снять с трех параметров за один раз и добавить дочерний объект.
void addChildren(vector>& theVector)
{}
template
void addChildren(vector>& theVector,
FirstChild childtype, FirstArg1&& arg1, FirstArg2&& arg2, Rest&&... rest)
{
addChild(theVector, childtype,
std::forward(arg1), std::forward(arg2));
addChildren(theVector, std::forward(rest)...);
}
template
vector> CreateVec(Args&&... args)
{
vector> result;
addChildren(result, std::forward(args)...);
return result;
}
Я принимаю здесь существование функции addChild
, который может добавить ребенка, учитывая его тип (в качестве параметра) и его аргументы.
Основная проблема с этим состоит в том, что у VS2012 нет variadic шаблонов. Есть два способа моделировать variadic шаблоны. 1. Напишите единственную функцию, которая берет максимальное количество параметров, в которых вы, возможно, нуждались бы, и дефолты большинство из них к некоторому известному типу, который можно взять, чтобы означать "не существующий". 2. Выпишите столько перегрузок, сколько вы думаете, что вам будет нужно.
Если вы знаете, что вам никогда не будут нужны больше, чем говорят десять дочерних объектов, второй вариант на самом деле совершенно выполним - только необходимо написать им однажды, и это - вероятно, меньше чем 150 линий кода. Альтернативно можно использовать Повышение. Препроцессор, чтобы произвести функции, но это - совершенно новый уровень сложности.