自动生成代码以在 C++ 中打印结构的每个字段
auto generate code to print each field of struct in c++
我的结构如下,同样可以有多个结构和多个字段。
struct A
{
int a;
int b;
char * c;
float d
};
现在如果我想打印上面结构的每个字段我需要手动输入,
cout << A.a << endl;
cout << A.b << endl;
cout << A.c << endl;
cout << A.d << endl;
如你所见,上面的东西是手动重复的任务,有什么办法可以自动生成上面的东西。
如果有人可以提供 eclipse 的代码模板,那将很有用。
我认为您可以在 struct A
中创建一个打印所有成员的方法。在需要使用 A.PrintInternalData()
.
打印所有数据的任何地方调用它
#include<iostream>
struct A
{
int a;
int b;
char * c;
float d
void PrintInternalData()
{
std::cout<<A.a<<std::endl;
std::cout<<A.b<<std::endl;
std::cout<<A.c<<std::endl;
std::cout<<A.d<<std::endl;
}
};
C++ 本身不支持反射和内省。您无法检查类型并查询它包含哪些成员或函数。您几乎无法做到这一点 "manually" 或使用添加反射的库(例如 boost reflect 或 Qt,它还为派生的 QObject 类 提供有限版本)。
有一种方法可以自动枚举和输出任何 structure/class 的所有字段,但它可能仅从 C++20 标准开始通过解包操作(例如 auto [a, b] = obj;
)存在。接下来的代码解决了你对任何结构的任务,你的结构被用作例子,用法例子见代码最后的main()
函数:
#include <iostream>
#include <tuple>
#include <type_traits>
template <auto I>
struct any_type {
template <class T> constexpr operator T &() const noexcept;
template <class T> constexpr operator T &&() const noexcept;
};
template <class T, auto... Is>
constexpr auto detect_fields_count(std::index_sequence<Is...>) noexcept {
if constexpr (requires { T{any_type<Is>{}...}; })
return sizeof...(Is);
else
return detect_fields_count<T>(std::make_index_sequence<sizeof...(Is) - 1>{});
}
template <class T>
constexpr auto fields_count() noexcept {
return detect_fields_count<T>(std::make_index_sequence<sizeof(T)>{});
}
template <class S>
constexpr auto to_tuple(S & s) noexcept {
constexpr auto count = fields_count<S>();
if constexpr (count == 8) {
auto & [f0, f1, f2, f3, f4, f5, f6, f7] = s;
return std::tie(f0, f1, f2, f3, f4, f5, f6, f7);
} else if constexpr (count == 7) {
auto & [f0, f1, f2, f3, f4, f5, f6] = s;
return std::tie(f0, f1, f2, f3, f4, f5, f6);
} else if constexpr (count == 6) {
auto & [f0, f1, f2, f3, f4, f5] = s;
return std::tie(f0, f1, f2, f3, f4, f5);
} else if constexpr (count == 5) {
auto & [f0, f1, f2, f3, f4] = s;
return std::tie(f0, f1, f2, f3, f4);
} else if constexpr (count == 4) {
auto & [f0, f1, f2, f3] = s;
return std::tie(f0, f1, f2, f3);
} else if constexpr (count == 3) {
auto & [f0, f1, f2] = s;
return std::tie(f0, f1, f2);
} else if constexpr (count == 2) {
auto & [f0, f1] = s;
return std::tie(f0, f1);
} else if constexpr (count == 1) {
auto & [f0] = s;
return std::tie(f0);
} else if constexpr (count == 0) {
return std::tie();
}
}
struct A {
int a;
int b;
char const * c;
float d;
};
int main() {
A a{.a = 1, .b = 2, .c = "c", .d = 3.14};
std::apply([](auto const &... x) {
((std::cout << x << std::endl), ...); }, to_tuple(a));
}
输出:
1
2
c
3.14
我的结构如下,同样可以有多个结构和多个字段。
struct A
{
int a;
int b;
char * c;
float d
};
现在如果我想打印上面结构的每个字段我需要手动输入,
cout << A.a << endl;
cout << A.b << endl;
cout << A.c << endl;
cout << A.d << endl;
如你所见,上面的东西是手动重复的任务,有什么办法可以自动生成上面的东西。 如果有人可以提供 eclipse 的代码模板,那将很有用。
我认为您可以在 struct A
中创建一个打印所有成员的方法。在需要使用 A.PrintInternalData()
.
#include<iostream>
struct A
{
int a;
int b;
char * c;
float d
void PrintInternalData()
{
std::cout<<A.a<<std::endl;
std::cout<<A.b<<std::endl;
std::cout<<A.c<<std::endl;
std::cout<<A.d<<std::endl;
}
};
C++ 本身不支持反射和内省。您无法检查类型并查询它包含哪些成员或函数。您几乎无法做到这一点 "manually" 或使用添加反射的库(例如 boost reflect 或 Qt,它还为派生的 QObject 类 提供有限版本)。
有一种方法可以自动枚举和输出任何 structure/class 的所有字段,但它可能仅从 C++20 标准开始通过解包操作(例如 auto [a, b] = obj;
)存在。接下来的代码解决了你对任何结构的任务,你的结构被用作例子,用法例子见代码最后的main()
函数:
#include <iostream>
#include <tuple>
#include <type_traits>
template <auto I>
struct any_type {
template <class T> constexpr operator T &() const noexcept;
template <class T> constexpr operator T &&() const noexcept;
};
template <class T, auto... Is>
constexpr auto detect_fields_count(std::index_sequence<Is...>) noexcept {
if constexpr (requires { T{any_type<Is>{}...}; })
return sizeof...(Is);
else
return detect_fields_count<T>(std::make_index_sequence<sizeof...(Is) - 1>{});
}
template <class T>
constexpr auto fields_count() noexcept {
return detect_fields_count<T>(std::make_index_sequence<sizeof(T)>{});
}
template <class S>
constexpr auto to_tuple(S & s) noexcept {
constexpr auto count = fields_count<S>();
if constexpr (count == 8) {
auto & [f0, f1, f2, f3, f4, f5, f6, f7] = s;
return std::tie(f0, f1, f2, f3, f4, f5, f6, f7);
} else if constexpr (count == 7) {
auto & [f0, f1, f2, f3, f4, f5, f6] = s;
return std::tie(f0, f1, f2, f3, f4, f5, f6);
} else if constexpr (count == 6) {
auto & [f0, f1, f2, f3, f4, f5] = s;
return std::tie(f0, f1, f2, f3, f4, f5);
} else if constexpr (count == 5) {
auto & [f0, f1, f2, f3, f4] = s;
return std::tie(f0, f1, f2, f3, f4);
} else if constexpr (count == 4) {
auto & [f0, f1, f2, f3] = s;
return std::tie(f0, f1, f2, f3);
} else if constexpr (count == 3) {
auto & [f0, f1, f2] = s;
return std::tie(f0, f1, f2);
} else if constexpr (count == 2) {
auto & [f0, f1] = s;
return std::tie(f0, f1);
} else if constexpr (count == 1) {
auto & [f0] = s;
return std::tie(f0);
} else if constexpr (count == 0) {
return std::tie();
}
}
struct A {
int a;
int b;
char const * c;
float d;
};
int main() {
A a{.a = 1, .b = 2, .c = "c", .d = 3.14};
std::apply([](auto const &... x) {
((std::cout << x << std::endl), ...); }, to_tuple(a));
}
输出:
1
2
c
3.14