使用 SFINAE 检查函数是否为 constexpr
Using SFINAE to check whether function is constexpr or not
我想检查一个函数是否可以在编译期间求值。我找到了 this,但我不完全理解这个概念。我有几个疑问:
代码中下面一行的作用是什么?
template<int Value = Trait::f()>
每次需要检查函数是否编译时可求值时,是否需要将其设为某个结构的成员函数?
PS
为了方便起见,我正在复制link中的代码。
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;
}
这只是一个简单的示例,说明您可以通过 std::void_t
获得什么来解决您的第 2 点,它在某种程度上可能是通用的...
#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;
};
我想检查一个函数是否可以在编译期间求值。我找到了 this,但我不完全理解这个概念。我有几个疑问:
代码中下面一行的作用是什么?
template<int Value = Trait::f()>
每次需要检查函数是否编译时可求值时,是否需要将其设为某个结构的成员函数?
PS
为了方便起见,我正在复制link中的代码。
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;
}
这只是一个简单的示例,说明您可以通过 std::void_t
获得什么来解决您的第 2 点,它在某种程度上可能是通用的...
#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;
};