如何将对象字段作为函数参数(特征向量)传递

How to pass Object Fields as Function Parameters (feature vector)

本文关键字:参数 特征 向量 传递 函数 对象 字段      更新时间:2023-10-16

我想写一个函数,将两个对象和它们的字段数组作为参数传递给它,以计算相似性的度量。

假设我有两个对象A和B,它们有A.size、A.weight、A.color、A.id.等字段

现在我想要一个函数,用这些参数得到大小为2的数组,所以它看起来像这样:

double measureSim (Car a, Car b, ??? feature[2]){
 double value = 0;
 for(int i = 0; i < feature.size; i++){
    double += (A.feature[i] - B.feature[i]);
 }
return value
}

我希望你能理解我想说的话。

EDIT:重点是制作一个可以比较两个对象的任意文件的函数。例如,在群集时。我希望能够告诉函数要考虑哪些字段。

如果您试图传递某种"对field成员名称的引用"数组,并以这种方式迭代一个类,那么您将无法以这种方式完成。不能在类型的成员上循环。

您可以将指针数组传递给成员:

#include <iostream>
#include <vector>
// (all doubles for exposition)
struct Car
{
    double size;
    double weight;
    double color;
    double id;
};
typedef double Car::*ptrToCarMember;
double measureSim(const Car& a, const Car& b, std::vector<ptrToCarMember> feature)
{
    double value = 0;
    for (auto el : feature) {
        value += a.*el - b.*el;
    }
    return value;
}
int main()
{
    Car a = { 1.0, 2.0, 4.0, 8.0 };
    Car b = { 1.0, 2.0, 3.0, 4.0 };
    {
        std::vector<ptrToCarMember> features{&Car::size};
        std::cout << measureSim(a, b, features) << 'n';
    }
    {
        std::vector<ptrToCarMember> features{&Car::id};
        std::cout << measureSim(a, b, features) << 'n';
    }
    {
        std::vector<ptrToCarMember> features{&Car::size, &Car::weight, &Car::color};
        std::cout << measureSim(a, b, features) << 'n';
    }
}
// $ g++ -std=c++11 -Wall main.cpp && ./a.out
// 0
// 4
// 1

(现场演示)

但是,哎呀!很少会发现需要指向成员的指针。也许你找到了一个很好的理由。只要确保很好地记录您的需求和代码。还要注意,要以这种方式使用的所有成员都必须具有相同的类型(此处为double);你不能混搭。

使用可变模板可能会更习惯,但我不打算在这里讨论,因为这是一个高级主题,可能会过于夸张。

您还可以简单地将成员变量替换为std::map,然后您可以对映射的键和值执行大量操作,而不需要"魔术"。

假设所有字段都是同一类型(比如float),那么您正在寻找指向成员的指针。语法如下:

// An example class with two fields to choose from
class A {
    float f1;
    float f2;
};
int main(int, char**) {
    // Declaration of a pointer-to-member
    float A::*ptr;
    // Assignment, note that we don't have an instance yet
    ptr = &A::f1;
    // Creating an actual instance
    A a;
    // Using the pointer on the instance
    a.*ptr = 3.14f;
    // Check that it worked. It did !
    std::cout << a.f1 << 'n';
    return 0;
}

你可能想要传递一个数组。

如果它们而不是都是相同的类型,那么您将需要更多的方法,使用模板风格的类型擦除。