问:有没有办法在operatorClass的构造函数中选择它所操作的容器中的哪个成员对象? (iter-> b而不是iter-> a)
更多细节:
我想我已经尽可能地简化了这一点,但我们会看到人群的想法。我有一个抽象模板类用于我使用了十几次的算法。在算法的实现中,数学的具体细节不同,但整个过程是相同的。除了传递给算法的数据结构中成员对象的名称之外,还有一些实现的对,其中数学是相同的。
在我的示例中,我希望能够在operatorClass的构造函数中定义函数操作的myContainer的哪个成员。
我可以添加另一个抽象级别来定义此行为吗?
目标是不必复制myoperation
中完成的数学运算,只需使用find-and-replace将_a更改为_b。
main()中的星号和随后注释的_b
代码显示了我瞄准的实现。
#include <iostream>
#include <list>
struct myContainer
{
double a, b, c;
// Constructor
myContainer(double ia, double ib, double ic) {
a = ia;
b = ib;
c = ic;
};
};
class operatorClass
{
public:
operatorClass() {
// How to on implementation of class, tell the function
// operate_on_list_of_containers() which parameter to operate on?
};
double myoperation(const std::list<myContainer> *mylist) {
std::list<myContainer>::const_iterator iter = mylist.begin();
std::list<myContainer>::const_iterator end = mylist.end();
double sum_of_squares = 0;
while ( iter != end ) {
sum_of_squares += (iter->a * iter->a);
iter++;
}
return sum_of_squares;
};
};
int main() {
std::cout << "Hello world" << std::endl;
// Create a linked list of myContainer objects
myContainer mc1(2.1, 3.4, 7.2);
myContainer mc2(0.7, 2.9, 3.1);
myContainer mc3(5.2, 6.3, 0.83);
std::list<myContainer> mylist;
mylist.push_back(mc1);
mylist.push_back(mc2);
mylist.push_back(mc3);
// Create object for the algorithm
operatorClass myalgorithm_a;
// operatorClass myalgorithm_b; // ******
double ssq_a = 0;
//double ssq_b = 0;
ssq_a = myalgorithm_a.myoperation(&mylist);
//ssq_b = myalgorithm_b.myoperation(&mylist);
std::cout << "The SSQ for a is " << ssq_a << std::endl;
//std::cout << "The SSQ for b is " << ssq_b << std::endl;
return 0;
}
IRL,operatorClass是metropolis-hastings算法(MH)的抽象模板类的子类/实现。链表是必要的,因为链表的维度也是用生死过程估算的(每次迭代组合算法创建或杀死容器约20-30次)。
在我的问题中,我有几对相同的MH算法,只有一组参数不同(例如{prior_mass,mean_mass,mass}和{prior_width,mean_width,width})。我的示例包含这些参数中最复杂的子集(平均值,宽度),它们包含在链表
中答案 0 :(得分:3)
这是使用指针变量成员的完美借口:
以这种方式更改operatorClass
:
class operatorClass
{
private:
double myContainer::*ptr_;
public:
operatorClass(double myContainer::*ptr) {
ptr_ = ptr;
};
double myoperation(std::list<myContainer> *mylist) {
std::list<myContainer>::iterator iter = mylist->begin();
std::list<myContainer>::const_iterator end = mylist->end();
double sum_of_squares = 0;
while ( iter != end ) {
sum_of_squares += (*iter).*ptr_ * (*iter).*ptr_;
iter++;
}
return sum_of_squares;
};
};
然后,在main
:
operatorClass myalgorithm_a(&myContainer::a);
operatorClass myalgorithm_b(&myContainer::b);
operatorClass myalgorithm_c(&myContainer::c);
完成了!
PS:你的myoperation()
函数很奇怪。在现代C ++中,它将类似于:
double myoperation(const std::list<myContainer> &mylist) {
double sum_of_squares = 0;
for (auto &x: mylist) {
sum_of_squares += x.*ptr_ * x.*ptr_;
}
return sum_of_squares;
};
答案 1 :(得分:0)
只需传入一个可以是lambda的仿函数,就像使用std
库中的通用算法一样:
auto sum_of_squares = std::accumulate(mylist.begin(), mylist.end(), 0.0,
[](auto const&x, auto sum) { return sum + x.a*x.a; });