为对象成员提供隐式变量名以进行输出

时间:2014-08-31 14:34:13

标签: c++ struct implicit-conversion

以下是用于控制台输出的Struct类型对象的典型实现。

void print(List *L, int s) {
    for (int i = 0; i < s; i++){
        cout << L[i].member_1 << "\t\t"    // int
             << L[i].member_2 << "\t\t"    // string
             << L[i].member_3 << "\t\t"    // string
             << L[i].member_4 << "\t\t"    // string
             << L[i].member_5 << "\t\t"    // double
             << L[i].member_6 << "\t\t"    // double
             << L[i].member_7 << "\t\t"    // int
             << L[i].member_8 << "\t\t";   // char
    }
}

以上似乎比它更长。所以相反,我试图编写以下代码。

int n = sizeof(L)/sizeof(L[0]);

void print(List *L, int s) {
    for (int i = 0; i < s; i++) {
        for(int j = 0; j < n; j++) {
            cout << L[i].member_ << j << "\t\t";
        }
    }
}

正如你可能猜到的那样,我在JavaScript /后编译方面有所提升,所以写这样的东西似乎很自然。我知道我正在为编译器编写代码,那么如何实现上述代码呢?除了纠正我的代码之外,我还想对后勤方法提出反馈或批评,因为我的OOP现在非常多余。我正在寻找标准的解决方案/原始C ++代码。这是出于教育目的和寻找逻辑。

1 个答案:

答案 0 :(得分:3)

C ++中没有内置的反射机制。静态反射可能是即将发布的语言版本的主题,但是现在,没有通用的方法来枚举类的所有成员。因此,您必须在某处明确列出所有成员。但这可以在一个地方重复使用,这是一个例子:

template <typename F>
void for_each_member(List& l, F f)
{
    f(l.member_1);
    f(l.member_2);
    f(l.member_3);
    f(l.member_4);
    f(l.member_5);
    f(l.member_6);
    f(l.member_7);
    f(l.member_8);
}

此模板函数为给定List的每个成员调用一个仿函数。使用此工具,您的print函数可能如下所示:

struct print_member
{
    template <typename T>
    void operator()(const T& m)
    {
        cout << m << "\t\t";
    }
};

void print(List *L, int s)
{
    for (int i = 0; i < s; i++)
    {
        for_each_member(L[i], print_member());
    }
}

使用C ++ 14,我们甚至可以不使用print_member仿函数,而是使用带有auto参数的通用lambda:

void print(List *L, int s)
{
    for (int i = 0; i < s; i++)
    {
        for_each_member(L[i], [](const auto& m)
        {
            cout << m << "\t\t";
        });
    }
}