在 C++ 中传递结构时的可选逻辑

Optional logic when passing structures in c++

我也是编程新手,正在尝试将结构数组和 "option" 传递给函数。然后我希望该函数能够操作结构数组中的数据。

struct coordinates{
    int x;
    int y;
    int z;
}COORD;

选项参数是一个整数,它将指定要操作的结构部分。

  1. 操纵 x --- 选项 = 0
  2. 操纵 y --- 选项 = 1
  3. 操纵 z --- 选项 = 2

下面显示了一个例子。该函数采用结构数组并生成数据点指定数据点的 3 点移动平均值。我遇到的问题是我试图构建的程序在每个结构中都有 50 多个成员,因此手动写出每个 if 语句真的很乏味。我想问的是有没有更优雅的解决方案???

#include <iostream>

struct coordinates{
    int x;
    int y;
    int z;
}COORD;

int main() {
    COORD points[10];

    // Initialising points
    for(int i = 0, i < 10, i++){ 
        points[i].x = 1;
        points[i].y = 2;
        points[i].z = 3;
    }
                            //(struct,startpoint,option)
    std::cout << movingaverage(&points,3,1); // Output
}

int movingaverage(COORD *data, int start_point, int option){

    if(option == 0) {
        // Assigns the "start" value of the sum value.
        sum = data[start_point]->x;
        sum = sum + data[start_point - 1]->x;
        sum = sum + data[start_point + 1]->x;
    }

    else if(option == 1) {
        // Assigns the "start" value of the sum value.
        sum = data[start_point]->y;
        sum = sum + data[start_point - 1]->y;
        sum = sum + data[start_point + 1]->y;
    }
    else if(option == 2) {
        // Assigns the "start" value of the sum value.
        sum = data[start_point]->z;
        sum = sum + data[start_point - 1]->z;
        sum = sum + data[start_point + 1]->z;
    }
    sum = sum / n;
    return sum; //Sum is the moving average
}

您可以按照

class coordinates{
    private:
    int xyz[3]; //implementation detail(!)

public:
    int x() const { return xyz[0]; }
    int y() const { return xyz[1]; }
    int z() const { return xyz[2]; }

    //some relevant setters go here

    static int movingaverage(COORD *data, int start_point, int option){

        sum = data[start_point]->xyz[option];
        sum = sum + data[start_point - 1]->xyz[option];
        sum = sum + data[start_point + 1]->xyz[option];
    }
};

C++ 不支持反射,因此您不能迭代结构的成员。我这样做的方法是使用 getter 函数。

template<class Getter>
int movingaverage(COORD *data, int start_point, const Getter &get){
    auto sum = get(data[start_point]);
    sum = sum + get(data[start_point - 1]);
    sum = sum + get(data[start_point + 1]);
    return sum;
}

std::cout << "x: " << movingaverage(&points, 3, [](const COORD &coord){return coord.x;}) << '\n';
std::cout << "y: " << movingaverage(&points, 3, [](const COORD &coord){return coord.y;}) << '\n';
std::cout << "z: " << movingaverage(&points, 3, [](const COORD &coord){return coord.z;}) << '\n';

如果您或您的编译器对 lambda 部分感到困惑,您可以编写一个常规函数并传递它。

我建议使用一个简单的函子。

Class MovingAvg
{
MovingAvg(std::vector<Coordinate> *pSet);
void SetPointSet(std::vector<Coordinate> *p);

double operator()(int startPoint, int option)
{
   //calculation here. 
   double sum = 0;
   for(int i = -1; i <= 1; ++i)
   {
       switch(option)
         case 0:
           sum += pointSet[startPoint + i].x; //check for bounday conditions.
    .................

   }
   return sum / 3;
}

private:
//container
std::vector<Coordinate> *pointSet;
}

用作。

MovAvg mvG(pointSet);
double sum = mvG(startP, option); 

//如果必须更改点集,则更改私有成员。

仿函数在这种情况下非常方便。

指向成员的指针也是一个可能的解决方案;结合模板函数,成员可以是不同的类型。但是,是的,语法有些奇怪:

#include <iostream>
#include <vector>
using namespace std;

/// calculate the sum of a given structure member in a vector:
template <typename T, typename M>
M membersum(vector<T> array, M (T::*mptr)) {
    M sum = 0;
    for (int i=0; i<array.size(); i++) {
        sum += (array[i].*mptr);
    }
    return sum;
}

struct Point {
    Point(int x, int y, float z): x(x), y(y), z(z) {}
    int x;
    int y;
    float z;
};

int main() {
    vector<Point> points;
    points.push_back(Point(1,2,3.8));
    points.push_back(Point(1,2,4.5));
    points.push_back(Point(1,2,1.7));
    // your code goes here
    cout << "sum x: " << membersum(points, &Point::x) << endl;
    cout << "sum y: " << membersum(points, &Point::y) << endl;
    cout << "sum z: " << membersum(points, &Point::z) << endl;
    return 0;
}

我在 ideone.com.

上创建的这个示例