Не могу сказать, что знаю, как написать идиомати c Java, но я предполагаю, что этот шаблон в Java является альтернативой лямбда-выражениям в C ++. Я помню, как использовал анонимный класс длиной go, когда работал с Swing. Я думаю, что сделал что-то вроде этого:
button.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
// ...
}
});
Это сахар для наследования от класса и переопределения метода. Делать именно это не совсем так, как я хотел бы подключить прослушиватель событий в C ++. Я бы предпочел сделать это:
button.addMouseClickListener([](const MouseEvent &e) {
// ...
});
В случае прослушивателя событий замыкание должно быть сохранено в std::function
или что-то подобное. Это примерно такая же производительность, как и у виртуального вызова.
Я не очень много знаю о том, где вы используете этот класс, но если вам нужно сохранить его в стороне (например, прослушиватель событий или что-то еще), то объявив класс длинный путь или использование std::function
, вероятно, самые чистые варианты. Если вам не нужно хранить его в стороне (как политика для алгоритма), тогда вы можете использовать функтор. Конечно, вы можете хранить в стороне функтор, но он требует небольшого количества шаблонных механизмов и, вероятно, не стоит (хотя он обладает большей гибкостью).
struct MyPolicy {
int doSomething(int i) {
return i * 3;
}
double getSomething() const {
return d;
}
double d;
};
template <typename Policy>
void algorithm(Policy policy) {
// use policy.doSomething and policy.getSomething...
}
Использование функтора или лямбды с шаблоном имеет гораздо лучшую производительность, чем использование виртуальных функций. В приведенном выше примере компилятор может и, вероятно, встроит вызовы doSomething
и getSomething
. Это невозможно с виртуальными функциями.
Если бы я знал больше о реальной проблеме, которую вы пытаетесь решить, я мог бы написать более конкретный c и полезный ответ.
После просмотра обновленного вопроса у меня есть еще одно предложение. Это было бы для создания подкласса для пользовательских агрегатных функций. Конечно, это имеет множество ограничений.
template <typename Func>
class CustomAgg : public AggField {
public:
CustomAgg(int colIndex, Func func)
: AggField{colIndex}, func{func} {}
void reduce(DataRow &row) override {
func(value, row);
}
double output() override {
return value;
}
private:
Func func;
double value = 0.0;
// could add a `count` member if you want
};
auto agg_opr = Agg({
new CustomAgg{0, [](double &value, DataRow &row) {
value += row[0].doubleval() * (1 + row[1].doubleval());
}},
new Avg(1),
new Max(1)
});
Честно говоря, я думаю, что лучшее решение для вас - не пытаться реализовать функцию Java в C ++. Я имею в виду, если вам нужно обрабатывать несколько столбцов в какой-то конкретной операции c, то создайте класс только для этого. Не делайте ярлыков. Дайте ему имя, хотя вы можете использовать его только в одном месте.