У меня есть пара функций, которые я хотел бы заменить шаблоном. Они выглядят примерно так:
std::vector<double> generate_means(
std::mt19937& g, unsigned int N,
double lower = -1.0, double upper = 1.0
) {
std::uniform_real_distribution<double> dist(lower, upper);
std::function<double()> rng = std::bind(dist, g);
std::vector<double> res(N);
std::generate(std::begin(res), std::end(res), gen);
return res;
}
Элементам, которые нуждаются в абстракции, являются возвращаемый тип (только содержащийся тип, всегда vector
в порядке), аргументы после N
(например, lower
и upper
в данном случае) и распределение (например, std::uniform_real_distribution
).
Что бы я хотел примерно уметь написать:
auto generate_means = generate_template<
double, // results vector<double>
std::uniform_real_distribution, // uses uniform distro
double=-1.0,double=1.0 // with default args
>
auto generate_norm_deviates = generate_template<
double, // still provides vector<double>
std::normal_distribution, // different distro
double=0, double=1.0 // different defaults
>
auto generate_category_ids = generate_template<
unsigned int,
std::uniform_int_distribution,
unsigned int=0, unsigned int // again with two args, but only one default
>
У меня есть несколько частей
template <class NUMERIC>
using generator = std::function<NUMERIC()>;
template <class NUMERIC>
std::vector<NUMERIC> series(unsigned int length, generator<NUMERIC> gen) {
std::vector<NUMERIC> res(length);
std::generate(std::begin(res), std::end(res), gen);
return res;
};
но когда я пытаюсь собрать как, например
template <class NUMERIC, class DIST, class...Args>
std::vector<NUMERIC> generator_template(
std::mt19937& g, unsigned int N,
Args... args
) {
DIST<NUMERIC> dist(&args...);
generator<NUMERIC> gen = std::bind(dist, g);
return series(N, gen);
}
Я сталкиваюсь с ошибками компиляции (в данном случае error: expected unqualified-id
). Что бы я хотел примерно достижимо? Это правильный подход или мне нужно сделать что-то принципиально другое? Если это в правильном направлении, что я пропускаю?
EDIT:
Для ограничений приложения: я хотел бы иметь возможность объявлять генераторы со значениями по умолчанию для аргументов, но мне иногда нужно использовать их без значений по умолчанию. Отсутствие значений по умолчанию просто неудобно, но не смертельно. Пример:
//... assorted calculations...
auto xmeans = generate_means(rng, 100); // x on (-1,1);
auto ymeans = generate_means(rng, 100); // y on (-1,1);
auto zmeans = generate_means(rng, 100, 0, 1); // z on (0,1);