在结构体中声明boost pfr char数组时,出现编译错误

问题描述 投票:0回答:1

在结构体中声明char数组时,达到一定大小时出现编译错误 在升压 1.84 中 需要 C++20。

#include <iostream>
#include <string>

#include <boost/pfr.hpp>
#include <boost/pfr/core.hpp>
#include <boost/pfr/core_name.hpp>
#include <boost/type_index.hpp>

struct Foo
{
    //std::string attr01;    // Compile OK
    //std::string attr02;    // Compile OK 
    //std::string attr03;    // Compile 0K

    char attr01[600];      // Compile Error
    //char attr02[100];
    //char attr03[200];
    //char attr04[600];
    //char attr05[600];
    //char attr06[600];
    //char attr07[600];
    //char attr08[600];
    //char attr09[600];
    //char attr10[600];
    //char attr11[600];
    //char attr12[600];
    //char attr13[600];
    //char attr14[600];
    //char attr15[600];
    //char attr16[600];
    //char attr17[600];
    //char attr18[600];
    //char attr19[600];
    //char attr20[600];
};

int main() {

    Foo foo;
    auto names = boost::pfr::names_as_array<Foo>();

    boost::pfr::for_each_field(foo, [&names](const auto& field, std::size_t idx) {
        std::cout << names[idx] << " : " << boost::typeindex::type_id_runtime(field) << "\n";
    });

    return 0;
}

输出 编译出现错误 错误:C2672 'boost::pfr::detail::name_of_field':没有匹配的重载函数。

c++ boost structure
1个回答
0
投票

来自文档

Boost.PFR 库适用于满足 SimpleAggregate 要求的类型:没有基类、const 字段、引用或 C 数组的聚合类型:

还有

该库可以使用不满足 SimpleAggregate 要求的聚合,但行为往往是不可移植的。

再往下:

有关限制的详细信息 Boost.PFRs 反射具有一些限制,这些限制取决于 C++ 标准和编译器功能:

  • 静态变量被忽略
  • T 必须是可聚合初始化的,无需基类
  • 如果 T 包含 C 数组,则反射的结果可能会因 C++ 版本和库配置而异
  • 额外限制,如果
    BOOST_PFR_USE_CPP17 == 0
    • 所有成员字段都不应具有来自一个参数的模板构造函数。
    • 额外限制,如果
      BOOST_PFR_USE_LOOPHOLE == 0
      • T 必须是 constexpr 聚合可初始化且其所有字段必须是 constexpr 默认可构造
      • boost::pfr::get
        boost::pfr::structure_to_tuple
        boost::pfr::structure_tie
        boost::pfr::tuple_element
        需要
        T
        成为仅具有内置类型的 POD 类型。

确实,要避免使用 C 风格的数组。请改用

std::array
。您可以通过包装类似元组的内容来强制解决此问题:

住在Coliru

#include <boost/pfr.hpp>
#include <boost/type_index.hpp>
#include <iostream>

static auto constexpr N = 600;
struct Foo { std::tuple<char[N]> forced; };
struct Bar { std::array<char, N> array; };

template <typename T>
static void test(T obj) {
    auto names = boost::pfr::names_as_array<T>();

    boost::pfr::for_each_field(obj, [&names](auto const& field, std::size_t idx) {
        std::cout << names[idx] << " : " << boost::typeindex::type_id_runtime(field) << "\n";
    });
}

int main() {
    test(Foo{});
    test(Bar{});
}

打印例如

forced : std::tuple<char [600]>
array : std::array<char, 600ul>
© www.soinside.com 2019 - 2024. All rights reserved.