使用不同的enable_if条件选择方法



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

我正在张贴我的示例代码。可以有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;
} 

if constexpr可以是部分编译的一种方法,但if内部的条件必须始终是可编译的。在您的情况下,v1<St>v2<St>仅在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;
}

现在is_v1<St>is_v2<St>总是返回一些值(truefalse(,代码应该编译1


1f2()中也有一个拼写错误:oh.i == 1 and oh.j == 1应该是oh.i == 1 && oh.j == 1

还要注意,h.i == 1 ? true : false是同义词,只要h.i == 1就足够了。

最新更新