在进行模板推导时,是否可以检测一个 consteval 函数是否可以 运行
While template deduction, is it possible to detect if a consteval function could be run
假设我们有一个 consteval
函数或一个带有 consteval
构造函数的普通结构,它只接受一些值:
struct A
{
consteval A(int a)
{
// compile error if a < 0
if (a < 0)
throw "error";
}
};
有什么方法可以检测这样的构造函数是否可以接受 int 的非类型模板参数?我尝试了以下代码但失败了。
template <int a> concept accepted_by_A = requires() {A(a);};
int main()
{
std::cout << accepted_by_A<-1> << std::endl; // output 1 (true)
}
由于调用抛出的 constexpr
(或 consteval
)函数不是常量表达式,您可以检测到:
template<int I> concept accepted_by_A=
requires() {typename std::type_identity_t<int[(A(I),1)]>;};
static_assert(accepted_by_A<1>);
static_assert(!accepted_by_A<-1>);
也可以使用 SFINAE(这将允许它在以前的语言版本中使用 constexpr
):
template<int,class=void> struct test : std::false_type {};
template<int I> struct test<I,decltype(void((int(*)[(A(I),1)])nullptr))> : std::true_type {};
static_assert(test<1>());
static_assert(!test<-1>());
替代专业化
template<int I> struct test<I,typename voided<int[(A(I),1)]>::type> : std::true_type {};
似乎它应该工作但没有;在某些情况下替换非类型模板参数很奇怪。
假设我们有一个 consteval
函数或一个带有 consteval
构造函数的普通结构,它只接受一些值:
struct A
{
consteval A(int a)
{
// compile error if a < 0
if (a < 0)
throw "error";
}
};
有什么方法可以检测这样的构造函数是否可以接受 int 的非类型模板参数?我尝试了以下代码但失败了。
template <int a> concept accepted_by_A = requires() {A(a);};
int main()
{
std::cout << accepted_by_A<-1> << std::endl; // output 1 (true)
}
由于调用抛出的 constexpr
(或 consteval
)函数不是常量表达式,您可以检测到:
template<int I> concept accepted_by_A=
requires() {typename std::type_identity_t<int[(A(I),1)]>;};
static_assert(accepted_by_A<1>);
static_assert(!accepted_by_A<-1>);
也可以使用 SFINAE(这将允许它在以前的语言版本中使用 constexpr
):
template<int,class=void> struct test : std::false_type {};
template<int I> struct test<I,decltype(void((int(*)[(A(I),1)])nullptr))> : std::true_type {};
static_assert(test<1>());
static_assert(!test<-1>());
替代专业化
template<int I> struct test<I,typename voided<int[(A(I),1)]>::type> : std::true_type {};
似乎它应该工作但没有;在某些情况下替换非类型模板参数很奇怪。