首页 > 解决方案 > 为结构/类中的所有字段调用相同的方法

问题描述

考虑以下代码。

struct Data {
  int a = 100;
  char* b = nullptr;
};

struct Data2 {
  int c = 100;
  char* d = nullptr;
};

template<typename T>
struct Test {
  T field;
  T field2;
};

int main()
{
  Test<Data> test;
  test.field.a = 500;
  test.field2.a = 500;

  Test<Data2> test2;
  test2.field.c = 1000;
  test2.field2.c = 1000;
}

我想要的是一种方法或运算符来做类似的事情

test.set<a> = {500, 500}
test2.set<c> = {1000, 1000}

基本上我想以某种方式指定字段名称,遍历所有结构字段并从给定的值列表中设置值。

我怀疑由于缺乏反射机制,标准 C++(任何标准)都无法解决该问题。我对这个假设是否正确?

标签: c++

解决方案


这样的事情怎么样?(利用数据成员指针)

struct Data
{
    int a;
};

template<class T>
struct test
{
    T field1, field2;
    template <class U, U (T::* p)>
    void set(U value)
    {
        field1.*p = value;
        field2.*p = value;
    }

};

int main()
{
    test<Data> t;
    t.set<int, &Data::a>(7);
}

我同意,写起来很拗口,但似乎或多或少地实现了(尽管以一种有点冗长和冗长的方式)你想要的。一个明显的缺点,我无法想到如何克服的一个缺点是,您需要在设置的模板参数中指定两者intData::而原则上编译器都知道这两者。

更新:这是另一种更清洁的解决方案

struct Data
{
    int a;
};

template<class T>
struct test
{
    T field1, field2;
    template <class U>
    void set(U(T::* p), const U* values)
    {
        field1.*p = *values++;
        field2.*p = *values++;
        //...
    }

};

int main()
{
    test<Data> t;
    int values[] = { 7, 8 };

    t.set(&Data::a, values);
}

推荐阅读