0

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?

7
  • Are you using C++20? If so, are you expecting f() to always be constexpr? If so, maybe f() should be consteval and not constexpr? To all of that, it seems to work here. Commented Jul 3 at 18:41
  • @PaulMcKenzie Unfortunately I have code inside of f() that requires a constexpr version of x. Even with consteval I get the same problem of x not being constexpr if I try to use it to initialise another constexpr variable (or use it as a template argument). Commented Jul 3 at 18:55
  • 2
    @sh1 You do not have code inside of f() that requires a constexpr version of x, uness you're asking us to fix code that we can't see. Please edit your question so the code accurately represents the problem you are trying to solve. The solution to the code you are showing is to change constexpr int y to int y. Commented Jul 3 at 18:57
  • "which seems a little unfair, because my intent is to [...]" -- (Regarding fairness:) How do you expect the compiler to know your intent? Mind reading is not a feature of current compilers. Commented Jul 3 at 19:29
  • Just the same way as it knows intent in most other constexpr cases. It just waits to see how it's used before it complains that it cannot reconcile the specific usage. Commented Jul 3 at 19:45

1 Answer 1

0

You already provided the solution by using a so-called non-type template parameter

template <int x>

To my knowledge, there is currently no other way to provide constexpr parameters to a function. That is literally what non-type template parameters are for.

However, there are restrictions regarding non-type template parameters (see Why can't I use std::string as a non-type template parameter?) and std:string or string literals are not allowed.

Sign up to request clarification or add additional context in comments.

4 Comments

or passing types using non-type template parameter such as std::integral_constant
Add C++20 add more allowed template parameters such as literal class type
So in cases where you want to pass, for example constexpr string_view and that's reflected, that's just a flaw of that specific type and I just have to use another type instead?
"rejected", I should say. Autocorrected and didn't notice until to late.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.