如何在构造时声明类操作的数据结构的哪个成员

时间:2018-03-15 23:10:25

标签: c++ c++11 linked-list

问:有没有办法在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})。我的示例包含这些参数中最复杂的子集(平均值,宽度),它们包含在链表

2 个答案:

答案 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; });