【发布时间】:2020-12-08 05:35:06
【问题描述】:
我想检查是否可以在编译期间评估函数。我找到了this,但我并不完全理解这个概念。我有几个疑问:
-
代码中下面这行的作用是什么?
template<int Value = Trait::f()> -
每次需要检查函数是否可编译时,是否需要将其设为某个结构的成员函数?
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;
}
【问题讨论】:
-
从总体上看,这里经常发布更多无用的问题,所以这里是一个赞成票,以抵消反对票。不要太在意偏离投票,它们只是附带损害......
-
template<int Value = Trait::f()>实际上要求可以在编译时评估Trait::f()。如果不能,则此重载不参与重载决议。如果存在,则它是do_call(0);的最佳匹配,但如果它被淘汰,则do_call(...)成为最佳匹配。 -
另一个问题是
constexpr函数可能只用于给定可能参数子集的常量表达式。所以f(0)无效,而f(42)是(constexpr int f(int i) { if (i == 0) throw std::runtime_error(".."); return i;}。
标签: c++ templates constexpr sfinae compile-time