如何在C 中实现公式模式
How to implement a formula pattern in C++?
免责声明
首先,我为这个问题的标题感到非常抱歉。我简单地制定想要的东西并不容易。如果您知道如何更改它 - 请,建议。
问题描述
预序
我有大量的结构化数据,这是不同类型的变量的树(root ttree对象)。该数据的基本单元被称为 entry 或事件。因此,不同的条目包含相同变量的不同值。后者不是最清晰的声明。以下面的方式考虑那棵树:就像矩阵一样,行是条目编号(0、1、2,...),列是可变名称( energy ,动量, theta ,...)。
我们需要的
我们需要对这些事件执行全球选择。IE。我们必须确定哪些事件是用于进一步分析的事件,哪些事件不是。为了达到此目的,我们开发了几种我们称为 Selectors 的算法。这些选择器使用事件(变量)的不同参数来决定是否通过。当前选择器背后的过程或算法我们将调用该算法使用的公式和变量 - variables 。。
我们正在按事件进行选择活动。IE。每个事件都通过每个选择器,如果其中某些选项失败(未传递)(选择器)(选择器)转弯。
编程问题
每个选择器由从抽象基类得出的类表示:
class Selector:
{
protected :
bool status;
public :
virtual bool Formula() = 0;//must be overridden for a specific Selector
};
您看到纯函数 Formula
没有任何参数。这是合理的,因为我们不知道应该采取什么论点,直到我们知道我们使用的选择器。因此,变量的信息可以存储在类数据成员中。例如,以这种方式
class SpecificSelector : public Selector
{
private :
std::vector<?> variables;//or std::array
public :
void AddVariable ( /*pointer to a variable*/ ) { variables.push_back( &variable ); }
bool Formula() { return ( *variables[0] + *variables[1] ) > 1 ? true : false; }
};
但是等等。变量可能是任何(合理的)类型。因此,我们必须知道什么是。可能是如此
class SpecificSelector : public Selector
{
private :
std::vector<int* > intVariables;//or std::array
std::vector<float* > floatVariables;
public :
void AddIntVariable ( /*pointer to a variable*/ ) { intVariables.push_back( &variable ); }
void AddFloatVariable ( /*pointer to a variable*/ ) { floatVariables.push_back( &variable ); }
bool Formula() { return ( *intVariables[0] + *intVariables[1] ) > 1 ? true : false; }
};
但是类型可能更具异国情调。例如。
也许这里是模板的地方?达到所需的方法是什么?如何实现这种Formula
成员函数。
尽管我们以这种特定的方式提出了问题,但我们认为问题很普遍。
如果您只想在事件循环外定义剪切,则可以做这样的事情。我假设您至少正在使用c++11
。root6
已需要年龄。
#include <iostream>
#include <type_traits>
#include <tuple>
#include <vector>
// Function that checks if calls to all tuple elements are true
template <typename T, size_t I = 0>
std::enable_if_t<(I+1 < std::tuple_size<T>::value),bool>
apply_cuts(T& cuts) { // base case
if (!std::get<I>(cuts)()) return false;
return apply_cuts<T,I+1>(cuts);
}
template <typename T, size_t I = 0>
std::enable_if_t<(I+1 == std::tuple_size<T>::value),bool>
apply_cuts(T& cuts) { // last cut
return std::get<I>(cuts)();
}
template <typename T, size_t I = 0>
std::enable_if_t<(std::tuple_size<T>::value == 0),bool>
apply_cuts(T&) { // no cuts
return true;
}
int main() {
// Open TFile
// Get TTree
// . . .
unsigned event;
double position;
int id;
std::vector<int> substructure;
// Set Branch Addresses
// . . .
// Instead of doing all that stuff with selectors that
// have pointers to the variables
// just capture variables by reference with lambda functions
auto cuts = std::make_tuple(
[&]{ return position > 2; },
[&]{ return id > 0; },
[&]{ return substructure.size() >= 3; }
);
// Event loop
// I'm emulating this part by hand below
// You would have something like this instead
/*
for (Long64_t i=0; i<num_events; ++i) {
tree->GetEntry(i);
if (!apply_cuts(cuts)) continue;
// Do something with selected events
// . . .
}
*/
// Test events
// Event 1
event = 1;
position = 65.65;
id = 5;
substructure = { 1,2,3,4 };
std::cout << "Event " << event << ": "
<< (apply_cuts(cuts) ? "passed" : "rejected") << std::endl;
// Event 2
event = 2;
position = 2.35;
id = -1;
substructure = { 1,2 };
std::cout << "Event " << event << ": "
<< (apply_cuts(cuts) ? "passed" : "rejected") << std::endl;
}
[wandbox] demo
std::enable_if_t<...>
是c++14
的句法糖。在c++11
中,您需要键入typename std::enable_if<...>::type
。
在c++17
中,您可以这样写apply_cuts
:
template <typename T>
bool apply_cuts(T& cuts) {
return std::apply([](auto&... x){ return (x() && ...); }, cuts);
}
- 下面抽象工厂设计模式的实现是正确的吗
- 虚拟模板函数:使用参数实现访客模式
- OpenCV 混合模式实现:为什么看似等效的操作会产生不同的结果?
- 为什么装饰器模式实现需要一个具有核心类的公共抽象超类
- 奇怪的是重复出现的模板模式实现
- 生成器模式实现中的不完整类型错误
- 我的双重检查锁定模式实现是否正确?
- 使用具有返回值的访客模式实现 AST 的最佳方法是什么?
- 使用桥接模式 c++ 实现复制构造函数
- 通过双重检查锁定模式实现call_once
- C++ 状态模式实现:指向状态机的指针机制变得无效
- 为什么GoF建议在C++模板方法模式实现中使用受保护的(而不是私有的)虚拟方法
- 如何在装饰器模式实现中正确使用shared_ptr
- C++中Observer模式实现中的循环引用
- c++单例模式_实现和内存管理
- 单例模式实现错误
- 如何使用复合模式实现菜单
- 带有数组的c++装饰器模式实现
- 这个工厂模式实现有什么问题吗?
- 使用策略设计模式实现输入类