c++ - 在模板推导时,是否可以检测是否可以运行 consteval 函数

标签 c++ templates c++20 consteval

假设我们有一个 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 {};

似乎它应该工作但没有;在某些情况下,替换非类型模板参数很奇怪。

关于c++ - 在模板推导时,是否可以检测是否可以运行 consteval 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70373555/

相关文章:

c++ - 如果 `if constexpr` 不匹配则停止编译

C++ 模板允许丢弃 const 引用限定符

c++ - 具有模板构造函数特化的模板类,用于初始化模板化基类

c++ - header 中的 "inline"是否需要 "void f(auto) {}"?

c++ - 如何将引用作为信号而不是对象传递

c++ - 尝试在 Xcode 5 中包含头文件。找不到文件

C++:调用 tuple_transpose 函数时没有匹配的函数调用

c++ - 如何定义任意 std::vector 满足的概念?

c++20 msvc错误c3861找不到基本成员

c++ - 从C++中的地址引用返回值