简体   繁体   English

如何将结构/联合数组的成员传递给函数

[英]How to pass member of structure/union array into function

For example, I want to display value of only one member of structure/union array, so I want to pass it as argument into a function that will display only that one member and will also display any other single member that I pass as argument. 例如,我只想显示结构/联合数组的一个成员的值,所以我想将其作为参数传递给一个函数,该函数将仅显示该成员并显示我作为参数传递的任何其他单个成员。

#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????
}

One option would be a templated pointer-to-member type . 一种选择是模板化的成员指针类型 These are usually used with class or struct types, but are also valid with a union type. 这些通常与classstruct类型一起使用,但对union类型也有效。 A pointer-to-member type is declared like MemberType ClassType::*pointer_name , and the name of such a pointer can be used to the right of the .* or ->* operator. 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;
}

And you create a pointer-to-member value with the syntax &ClassType::member_name : 然后使用&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);
}

Another more general option would be to take a callable functor: 另一个更通用的选择是采用可调用函子:

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

You can create a functor to access a member using a lambda or std::mem_fn : 您可以使用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));
}

But defining showArr this way also lets you pass a functor that does something more complicated than just return a member, if you wanted: 但是, showArr这种方式定义showArr还可以使您传递函子,该函子的作用比返回成员要复杂得多,如果需要的话:

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

In C++17 you should use std::variant : 在C ++ 17中,您应该使用std::variant

using ThreeTypes = std::variant<char, int, double>;

template <std::size_t N>
auto show_arr(std::array<ThreeTypes, N>& arr)
{
    for (auto& e : arr)
    {
        std::visit([](auto e) { std::cout << e << std::endl;}, e);
    }
}

auto test()
{
    std::array<ThreeTypes, 2> arr = {3.4, 'a'};

    show_arr(arr);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM