例如,我只想显示结构/联合数组中一个成员的值,所以我想将其作为参数传递给一个函数,该函数将仅显示该成员并显示我传递的任何其他单个成员作为争论。
#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????
}
答案 0 :(得分:6)
一个选项是模板化的pointer-to-member type。这些通常与class
或struct
类型一起使用,但也与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;
}
然后您使用语法&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);
}
另一个更通用的选择是采用可调用函子:
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;
}
您可以创建函子以使用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));
}
但是,通过这种方式定义showArr
也可以让您传递函子,该函子的作用比返回一个成员还要复杂,如果需要的话:
void print_sin2x_all(const ThreeTypes arr[], int size)
{
showArr(arr, size, [](const ThreeTypes& u) { return std::sin(2*u.real); });
}
答案 1 :(得分:2)
在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);
}