简体   繁体   中英

Instantiating template function in a false if constexpr gives error

Consider the following program:

#include <iostream>

template<typename... Params_t>
constexpr int constexprValue(Params_t...) { return 5; }

int main()
{
    const bool flag = true;

    if constexpr(flag)
    {
        constexpr int value = constexprValue(1, 2, 3);
        std::cout << value << "\n";
    }
}

This compiles and works fine. However, if flag is changed to false , then clang (Apple LLVM version 10.0.0 (clang-1000.10.44.4)) gives a compiler error:

error: constexpr variable 'value' must be initialized by a constant expression
undefined function 'constexprValue<int, int, int>' cannot be used in a constant expression

Is this a bug in clang?

Yes, it seems to be a bug in the Apple version of clang, I'm able to compile the code with clang version 5 and greater as well as gcc version 7.1 and greater.

Matt Godbold has a great website for compiling snippets of code with a slew of different compilers.

Here is a link to your example in godbolt.

Yes this is a bug it was fixed by this commmit to clang: [Sema] Discarded statment should be an evaluatable context. which has the following description:

The constexpr evaluator was erroring out because these templates weren't defined. Despite being used in a discarded statement, we still need to constexpr evaluate them, which means that we need to instantiate them. Fixes PR37585.

Differential revision: https://reviews.llvm.org/D48322

and includes the following test:

namespace PR37585 {
template <class T> struct S { static constexpr bool value = true; };
template <class T> constexpr bool f() { return true; }
template <class T> constexpr bool v = true;

void test() {
  if constexpr (true) {}
  else if constexpr (f<int>()) {}
  else if constexpr (S<int>::value) {}
  else if constexpr (v<int>) {}
}
}

If we try the test live with godbolt with an older clang version we obtain a very similar erroneous diagnostic that your example is seeing:

error: constexpr if condition is not a constant expression
else if constexpr (f<int>()) {}
                   ^~~~~~~~

note: undefined function 'f<int>' cannot be used in a constant expression

the fix originated from bug report: constexpr if condition is not a constant expression and std::is_same .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM