Using SFINAE to check whether function is constexpr or not

Viewed 116

I want to check whether a function can be evaluated during compilation. I found this, but I don't understand the concept completely. I have a few doubts:

  1. What is the role of the following line in the code?
    template<int Value = Trait::f()>

  2. Every time when I need to check whether the function is compile-time evaluable, Do I need to make it a member function of some struct?

PS
I am copying the code in the link, just for convenience.

template<typename Trait>
struct test
{
    template<int Value = Trait::f()>
    static std::true_type do_call(int){ return std::true_type(); }

    static std::false_type do_call(...){ return std::false_type(); }

    static bool call(){ return do_call(0); }
};

struct trait
{
    static int f(){ return 15; }
};

struct ctrait
{
    static constexpr int f(){ return 20; }
};

int main()
{
   std::cout << "regular: " << test<trait>::call() << std::endl;
   std::cout << "constexpr: " << test<ctrait>::call() << std::endl;
}
1 Answers

Here is just a quick example of what you can get with std::void_t to tackle your point 2 that can be generic in some way...

#include <iostream>
#include <type_traits>

int f() {
    return 666;
}

constexpr int cf(int, double) {
    return 999;
}

template <auto F>
struct indirection {
};

template<typename F, class = std::void_t<> >
struct is_constexpr : std::false_type { };

template<typename F, typename... Args>
struct is_constexpr<F(Args...),
           std::void_t<indirection<F(Args{}...)>>
       > : std::true_type { };

int main()
{
   std::cout << is_constexpr<decltype(f)>::value << std::endl;
   std::cout << is_constexpr<decltype(cf)>::value << std::endl;
};

Demo here

Related