如何将structure/union数组的成员传递给函数

din*_*018 0 c++ c++17

例如,我想显示结构/联合数组的一个成员的值,所以我想将它作为参数传递给一个只显示一个成员的函数,并且还将显示我作为参数传递的任何其他单个成员.

#include <iostream>
using namespace std;

union ThreeTypes
{
    char letter;
    int whole;
    double real;
};

void showArr(ThreeTypes[], int); // ?? What parameters to pass?

int main()
{
    const int SIZE = 50;
    ThreeTypes arr[SIZE];
    for (int i = 0; i < SIZE; i++)
        arr[i].real = 2.37;

    showArr(arr, SIZE, ??? ); // what argument to pass to display member?

    return 0;
}
void showArr(ThreeTypes arr[],int size,???) // also, what parameters??
{
    for (int i = 0; i < size; i++)
        cout << arr[i].?? << endl; // member from argument????
}
Run Code Online (Sandbox Code Playgroud)

asc*_*ler 6

一个选项是模板化指针到成员类型.这些通常与classstruct类型一起使用,但对类型也有效union.指向成员的指针类型被声明为MemberType ClassType::*pointer_name,并且这样的指针的名称可以用于.*->*运算符的右侧.

template <typename T>
void showArr(const ThreeTypes arr[], int size, T ThreeTypes::*ptr)
{
    for (int i = 0; i < size; ++i)
        std::cout << (arr[i].*ptr) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

然后使用以下语法创建指向成员的指针值&ClassType::member_name:

int main()
{
    const int SIZE = 50;
    ThreeTypes arr[SIZE];
    for (int i = 0; i < SIZE; i++)
        arr[i].real = 2.37;

    showArr(arr, SIZE, &ThreeTypes::real);
}
Run Code Online (Sandbox Code Playgroud)

另一个更通用的选择是采用可调用的函子:

template <typename F>
void showArr(const ThreeTypes arr[], int size, const F& func)
{
    for (int i = 0; i < size; ++i)
        std::cout << func(arr[i]) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

您可以使用lambda创建一个仿函数来访问成员,或者std::mem_fn:

void print_reals_twice(const ThreeTypes arr[], int size)
{
    showArr(arr, size, [](const ThreeTypes& u) { return u.real; });
    // Same effects:
    showArr(arr, size, std::mem_fn(&ThreeTypes::real));
}
Run Code Online (Sandbox Code Playgroud)

但是showArr如果你想要的话,定义这种方式还可以让你传递一个更复杂的函子,而不仅仅是返回一个成员:

void print_sin2x_all(const ThreeTypes arr[], int size)
{
    showArr(arr, size, [](const ThreeTypes& u) { return std::sin(2*u.real); });
}
Run Code Online (Sandbox Code Playgroud)