C++ 使用不同的启用条件选择方法

C++ 使用不同的启用条件选择方法,c++,templates,c++17,c++20,C++,Templates,C++17,C++20,我想写一个通用的验证函数。所以我试着写一个元程序。 但它没有被编译,这是正确的。谁能告诉我一个实现它的方法吗 我张贴我的样本代码。可以有3种或更多类型的结构(这里是A、B、C),有些具有特定类型的头,另一些具有其他类型的头,有些甚至没有头。因此,我想编写一个程序,正确地选择所需的函数(这里是f1(),f2())来验证结构头。我不想使用Boost Hana或任何其他反射库 #include <iostream> using namespace std; struct Header

我想写一个通用的验证函数。所以我试着写一个元程序。 但它没有被编译,这是正确的。谁能告诉我一个实现它的方法吗

我张贴我的样本代码。可以有3种或更多类型的结构(这里是A、B、C),有些具有特定类型的头,另一些具有其他类型的头,有些甚至没有头。因此,我想编写一个程序,正确地选择所需的函数(这里是f1(),f2())来验证结构头。我不想使用Boost Hana或任何其他反射库

#include <iostream>

using namespace std;

struct Header
{
    int i;
};

struct OrderHeader
{
    int i; int j;
};

struct A
{
    Header header;
    int val;
};

struct B
{
    OrderHeader order_header;
    int val;
    int c;
};

struct C
{
    int val;
    int c;
};

bool f1(Header h)
{
    return h.i == 1 ? true : false;
}

bool f2(OrderHeader oh)
{
    return (oh.i == 1 and oh.j == 1) ? true : false;
}

template<typename St, typename = enable_if_t<is_same_v<decltype(St::header), Header>>>
using v1 = bool;

template<typename St, typename = enable_if_t<is_same_v<decltype(St::order_header), OrderHeader>>>
using v2 = bool;

template<typename St>
bool validate(St s)
{    
    if constexpr(is_same_v<v1<St>, bool>)
    {
        return f1(s.header);
    }
    else if constexpr(is_same_v<v2<St>, bool>)
    {
        return f2(s.order_header);
    }
    
    return true;
}

int main(int argc, char** argv) 
{         
    A at{1,1};
    A af{};
    C c{};    
    B b{};
    
    cout << boolalpha << validate(at) << endl;
    cout << boolalpha << validate(af) << endl;
    cout << boolalpha << validate(b) << endl;
    cout << boolalpha << validate(c) << endl;
    
    return 0;
} 
#包括
使用名称空间std;
结构头
{
int i;
};
结构OrderHeader
{
int i;int j;
};
结构A
{
收割台;
int-val;
};
结构B
{
订单头订单头;
int-val;
INTC;
};
结构C
{
int-val;
INTC;
};
bool f1(收割台h)
{
返回h.i==1?真:假;
}
bool f2(订单头oh)
{
return(oh.i==1和oh.j==1)?true:false;
}
模板
使用v1=bool;
模板
使用v2=bool;
模板
bool验证(St s)
{    
如果constexpr(是否相同)
{
返回f1(s标题);
}
如果constexpr(是否相同)
{
返回f2(s.order_标题);
}
返回true;
}
int main(int argc,字符**argv)
{         
A在{1,1}处;
A af{};
C{};
B{};

cout
if constexpr
可以作为部分编译的方法,但是
if
中的条件必须始终是可编译的。在您的情况下,
v1
v2
仅在
St
类型正确时才存在,因此会出现错误

您可以使用变量模板的专门化,例如

template<typename, typename = void>
constexpr bool is_v1 = false;

template<typename St>
constexpr bool is_v1<St, enable_if_t<is_same_v<decltype(St::header), Header>>> = true;

template<typename, typename = void>
constexpr bool is_v2 = false;

template<typename St>
constexpr bool is_v2<St, enable_if_t<is_same_v<decltype(St::order_header), OrderHeader>>> = true;

template<typename St>
bool validate(St s)
{
    if constexpr (is_v1<St>)
    {
        return f1(s.header);
    }
    else if constexpr (is_v2<St>)
    {
        return f2(s.order_header);
    }

    return true;
}
模板
constexpr bool是_v1=false;
模板
constexpr bool是_v1=true;
模板
constexpr bool是_v2=false;
模板
constexpr bool为_v2=true;
模板
bool验证(St s)
{
如果constexpr(is_v1)
{
返回f1(s标题);
}
否则,如果constexpr(is_v2)
{
返回f2(s.order_标题);
}
返回true;
}
现在
is_v1
is_v2
总是返回一些值(要么
true
要么
false
),代码应该编译1


1在
f2()
中还有一个输入错误:
oh.i==1和oh.j==1
应该是
oh.i==1和&oh.j==1


另请注意
h.i==1?true:false
是同义反复的,只要
h.i==1
就足够了。

谢谢兄弟的回答。它解决了我的问题。我有一个错误的印象,如果一个条件不能被计算,那么constexpr如果离开那个条件。另外“and”不是拼写错误,它的同义词是&&。第二点被接受,只是忽略了:)