使用 SFINAE 检查函数是否为 constexpr

Kis*_*kla 5 c++ templates compile-time sfinae constexpr

我想检查一个函数是否可以在编译期间被评估。我发现了这个,但我不完全理解这个概念。我有几个疑问:

  1. 代码中下面这行的作用是什么?
    template<int Value = Trait::f()>

  2. 每次当我需要检查该函数是否可以在编译时评估时,是否需要将其设为某个结构的成员函数?

PS
我复制链接中的代码,只是为了方便。

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;
}
Run Code Online (Sandbox Code Playgroud)

小智 2

这只是一个简单的例子,说明你可以用什么std::void_t来解决你的第二点,在某种程度上可以是通用的......

#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;
};
Run Code Online (Sandbox Code Playgroud)

演示在这里