【问题标题】:auto generate code to print each field of struct in c++自动生成代码以在 C++ 中打印结构的每个字段
【发布时间】:2018-08-25 03:58:20
【问题描述】:

我有一个结构如下,同样可以有多个具有多个字段的结构。

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 的代码模板,那将很有用。

【问题讨论】:

标签: c++ eclipse editor auto-generate


【解决方案1】:

我认为您可以在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;
    }
};

【讨论】:

  • 我只是想避免手动工作,因为我有多个结构和多个字段。此外,我无法更改结构,因为所有这些结构都在给定库的接口中。
  • 好的,我明白你现在在寻找什么。我的坏!
  • 实际上在搜索了很多之后,你说的是我唯一要做的选择。所以我创建了一个脚本,在每个结构中生成该函数。所以我的工作已经完成,但我还在等待如果有人有更好的方法。
【解决方案2】:

C++ 本身不支持反射和内省。您无法检查类型并查询它包含的成员或函数。您几乎被困在“手动”或使用添加反射的库(如 boost reflect 或 Qt,它也为 QObject 派生类提供有限版本)。

【讨论】:

    【解决方案3】:

    存在一种自动枚举和输出任何结构/类的所有字段的方法,但它可能仅从 C++20 标准开始通过解包操作(例如auto [a, b] = obj;)。下一个代码可以解决任何结构的任务,以您的结构为例,用法示例见代码末尾的main() 函数:

    Try it online!

    #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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-02
      • 2019-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-14
      • 2012-12-14
      相关资源
      最近更新 更多