I would like to develop a compile-time evaluation for a static constexpr struct member. However, despite my efforts, I have been unable to get the code to function correctly.
The following code will explain what I want better.
struct s1 {
int a;
};
template <class T>
struct var {
const char* name;
int T::*offset;
};
constexpr int sum(auto&&... n)
{
return (n + ...);
}
template <var... Ts>
struct A {
int arg1;
static constexpr auto value = sum((int)Ts.offset...);
};
template <int... Ts>
struct B {
int arg1;
static constexpr auto value = sum(Ts...);
};
And this is how I'm reference it:
auto Works = B<1, 2, 3>::value; // works == 6
auto Help = A<{"a", &s1::a}>::value;
My final goal is to call the 3rd party function constexpr auto unknown(auto&&... args)
function instead of sum
, therefore I will need to expand my args as follow:
template <var... Ts>
struct C {
int arg1;
static constexpr auto value = unknown(Ts.name, Ts.offset ...);
};
That way it will expand to:
static constexpr auto value = unknown("a", &s1::a, "b", &s1::b ...);
An easy way is to take each var
in the Ts
pack, create a std::tuple<const char*, int T::*>
, then tuple_cat
these 2-tuples together, which you can apply
to your unknown
function:
// static constexpr auto value = unknown(Ts.name, Ts.offset ...);
static constexpr auto value = std::apply(
[](auto... args) { return unknown(args...); },
std::tuple_cat(std::tuple(Ts.name, Ts.offset)...)
);
And since you can't directly store a pointer to a string literal in a non-type template parameter, store the name directly in var
and this should compile:
template <class T, std::size_t N>
struct var {
const char name[N];
int T::*offset;
};
Example: https://godbolt.org/z/j1scWvhrx