My api would require calling runtime(constFoo(str)) to get the final result, I wanted to shorten this because the real function names are kind of verbose. To do this I need to somehow wrap the consteval function, but I can't do that since the argument cannot be constexpr, it's also a string literal which requires the its size to be known at compile time.
I'm aware of Pass const expression to consteval function through non-consteval functions but it doesn't really solve my issue because I need the size to be known at compile time.
int runtime(int val) {
std::string foo = "foo"; // some run time operation
return val + 2;
}
template <std::size_t N> consteval int constFoo(const char (&data)[N]) {
// ...
const auto d = data[0];
return N;
}
template <std::size_t N> int outer(const char (&data)[N]) {
int val = constFoo(data); // Call to consteval function 'constFoo<2ULL>' is not a constant expression
return runtime(val);
}
int main() {
auto d = outer("d");
}
Also if this would be somehow possible I'd rather avoid a solution where the literal is passed as a template argument, but as far as I'm aware this is impossible.
Since C++20, non-type template parameter allows some literal class types, so turn your string literal into one of those classes:
template <std::size_t N>
struct LiteralString
{
consteval LiteralString(const char (&s)[N]) { std::copy(s, s + N, &data[0]); }
static constexpr std::size_t size = N;
char data[N]{};
};
// [..]
template <LiteralString data>
int outer()
{
int val = constFoo(data.data);
return runtime(val);
}
int main()
{
auto d = outer<LiteralString("d")>();
// [..]
}
Demo
Make the parameter of the outer (non-consteval) function a class with a consteval constructor taking a string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With