A simple function like:
constexpr int f(int x) {
constexpr int y = x;
return y;
}
Seems to not be legal because x is not constexpr. This complaint is made even before I call the function, which seems a little unfair, because my intent is to only use it with arguments that are constexpr.
I can sort of work around that problem this with:
template <int x>
constexpr int f() {
constexpr int y = x;
return y;
}
But in real usage this becomes challenging because the argument might be something like a std::string_view instead of an int and that's not suitable as a template argument because it generates more complicated errors regarding the object's internal implementation.
Here's an illustration of where this matters:
constexpr std::array easy{'h', 'e', 'l', 'l', 'o'};
constexpr struct Hard {
constexpr Hard(int n) : size_(n) {}
size_t size_;
constexpr size_t size() const { return size_; }
} hard(10);
constexpr std::string_view nope{"hello"};
template <typename T>
constexpr auto f(T s) {
return std::array<char, s.size()>();
}
auto arr_easy = f(easy); // OK
auto arr_hard = f(hard); // `s` isn't constexpr even though `hard` is
auto arr_nope = f(nope); // `s` isn't constexpr even though `nope` is
// Alternative approach:
template <typename T, T s>
constexpr auto tf() {
return std::array<char, s.size()>();
}
auto tmpl_arr_easy = tf<decltype(easy), easy>(); // OK
auto tmpl_arr_hard = tf<decltype(hard), hard>(); // OK
auto tmpl_arr_nope = tf<decltype(nope), nope>(); // can't use std::string_view as template argument
How do I write a constexpr function which takes only constexpr arguments?
f()to always beconstexpr? If so, maybef()should beconstevaland notconstexpr? To all of that, it seems to work here.f()that requires aconstexprversion ofx. Even withconstevalI get the same problem ofxnot beingconstexprif I try to use it to initialise anotherconstexprvariable (or use it as a template argument).constexpr int ytoint y.