0

I have this piece of code:

template <typename T>
struct Base {
    constexpr std::uint8_t getValue() noexcept {
        return static_cast<T*>(this)->getValueImpl();
    }
};

class Derived : public Base<Derived> {
    friend struct Base<Derived>;

    constexpr std::uint8_t getValueImpl() noexcept {
        return sizeof(std::uint8_t);
    }
};

template <typename ...Args>
void doStuff(Args &&...args) {
    constexpr auto alrightVariable = sizeof...(args);
    constexpr auto errorVariable = (args.getValue() + ...);
}

int main() {
    doStuff(Derived());
    return 0;
}

And it throw compile error: "function parameter 'args' with unknown value cannot be used in a constant expression"

Where I was wrong? All variables can be calculated at compile time...

in_text
  • 21
  • 3
  • Function parameters are never constexpr. This means `args` in `args.getValue()` is not a compile time constant. See dupe: [Why do I get this error in Clang? "constexpr if condition is not a constant expression"](https://stackoverflow.com/questions/73125275/why-do-i-get-this-error-in-clang-constexpr-if-condition-is-not-a-constant-expr/73125474#73125474) – Jason Oct 12 '22 at 11:48
  • `constexpr alrightVariable = ` is not valid. What type `alrightVariable` supposed to have? – Jason Oct 12 '22 at 11:51
  • @JasonLiam sorry, fixed. – in_text Oct 12 '22 at 11:53
  • See the [dupe](https://stackoverflow.com/questions/73125275/why-do-i-get-this-error-in-clang-constexpr-if-condition-is-not-a-constant-expr/73125474#73125474). Function parameters like `args` are never `constexpr`. – Jason Oct 12 '22 at 11:54
  • 1
    This will be allowed in C++23, fixed via a defect report to the standard. If you let `doStuff` take its argument by-value it will work. This is an annoying issue specific to references. – user17732522 Oct 12 '22 at 11:55
  • To clarify: What I mean is that it will work when `args` is a non-reference _now_ and will work as reference as soon as compilers have implemented the defect report. – user17732522 Oct 12 '22 at 12:03
  • @user17732522 okay thanks, fix works! But in this case I also have a same error: `template std::uint32_t wrapper(Args ...args) { constexpr auto val = doStuff(args...); return val; } int main() { constexpr auto ret = wrapper(Derived()); return ret; }` – in_text Oct 12 '22 at 12:11
  • @in_text I don't know what you mean. Your `doStuff` is declared to return `void`, so that can't work. – user17732522 Oct 12 '22 at 12:15
  • @user17732522 `template constexpr std::uint32_t doStuff(Args ...args) { constexpr auto alrightVariable = sizeof...(args); constexpr auto errorVariable = (args.getValue() + ...); return alrightVariable + errorVariable; } template std::uint32_t wrapper(Args ...args) { constexpr auto val = doStuff(args...); return val; } int main() { constexpr auto ret = wrapper(Derived()); return ret; }` – in_text Oct 12 '22 at 12:17
  • @in_text Missing `constexpr` on `wrapper`. – user17732522 Oct 12 '22 at 12:19

0 Answers0