Search code examples
c++c++17if-constexpr

Why does min still complain inside constexpr?


I have the following code snippet:

#include <iostream>
#include <type_traits>
#include <algorithm>
#include <cstdint>
using T = double;

int main()
{
    f();
}
void f() {
    T x = 2;
    if constexpr(std::is_integral_v<T>)
    {
        std::cout << std::min(static_cast<int64_t>(2), x);
    } else {
    std::cout << std::min(1.0, x);
    }
}

The compiler is explaining that

<source>:15:57: error: no matching function for call to 'min(int64_t, T&)'

I thought it wouldn't be a problem because when T is a double, the first branch won't be instantiated. Apparently my understanding is wrong. Could someone help point out where my understanding goes wrong?


Solution

  • You need to make f() template, and T template parameter.

    template <typename T>
    void f() {
        T x = 2;
        if constexpr(std::is_integral_v<T>)
        {
            std::cout << std::min(static_cast<int64_t>(2), x);
        } else {
        std::cout << std::min(1.0, x);
        }
    }
    

    then

    int main()
    {
        f<double>();
    }
    

    For constexpr if:

    (emphasis mine)

    If a constexpr if statement appears inside a templated entity, and if condition is not value-dependent after instantiation, the discarded statement is not instantiated when the enclosing template is instantiated .

    Outside a template, a discarded statement is fully checked. if constexpr is not a substitute for the #if preprocessing directive:

    void f() {
        if constexpr(false) {
            int i = 0;
            int *p = i; // Error even though in discarded statement
        }
    }