1

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

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

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

  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
}
4

4 回答 4

1

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 部分感到困惑,您可以编写一个常规函数并传递它。

于 2015-05-30T10:41:24.447 回答
1

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

#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上创建的这个例子。

于 2015-05-30T10:58:35.047 回答
0

你可以尝试一些类似的东西

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];
    }
};
于 2015-05-30T10:37:43.643 回答
0

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

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); 

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

在这种情况下,函子非常方便。

于 2015-05-30T10:50:10.920 回答