如何开发 boost::pfr::for_each 的 constexpr 实现?

How to develop a constexpr implementation of boost::pfr::for_each?

我正在使用 boost::pfr,它使用反射的方式令人印象深刻,无需任何变量的宏注册。

但我想知道的问题是为什么 boost::pfr::for_each 没有声明为 constexpr,避免在当前情况下在用户声明的任何 constexpr 函数中使用 PFR for_each

有什么方法可以在不更改原始 boost::pfr 源代码的情况下绕过这个问题?

编辑:我在 coliru 中包含了一个工作示例和 link 来说明我的观点。

https://coliru.stacked-crooked.com/a/443f8bd2ad66ca4c

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

struct Variable
{
};

struct Var1 : public Variable
{
   static constexpr int size { 5 };
};

struct Var2 : public Variable
{
   static constexpr int size { 10 };
};

struct Var3//This one does not depend of class Variable!
{
   static constexpr int size { 20 }; 
};

struct Packet
{
    Var1 var1;
    Var2 var2;
    Var3 var3;
};

template<typename T>
constexpr int accumulate(const T& ref) {
    int result{};
    boost::pfr::for_each_field(ref, [&](auto& field) { if (std::is_base_of<Variable, std::decay_t<decltype(field)>>::value) result += field.size; });
    return result;
}

int main()
{
    Packet packet;
    /*constexpr*/ auto size = accumulate(packet);//constexpr must be commented!
    std::cout << size;
    //static_assert(size == 15);//It can not be used due to non-constexpr!
}

这看起来像是对实现的疏忽,因为它很容易成为 constexpr,至少对于 C++17 实现而言 - godbolt example

与此同时,您可以使用 boost::pfr::structure_tie(即 constexpr)& std::apply:

构建自己的 constexpr

godbolt example

template<class T, class F>
constexpr void for_each_field(T&& obj, F&& func) {
    std::apply([f = std::forward<F>(func)](auto&&... elements) mutable {
        (std::forward<F>(f)(std::forward<decltype(elements)>(elements)), ...);
    }, boost::pfr::structure_tie(std::forward<T>(obj)));
}