我想写一个通用的验证函数。所以我试着写一个元程序。但它没有被编译,这是正确的。有人能告诉我实现它的方法吗?
我正在张贴我的示例代码。可以有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>
总是返回一些值(true
或false
(,代码应该编译1。
1f2()
中也有一个拼写错误:oh.i == 1 and oh.j == 1
应该是oh.i == 1 && oh.j == 1
。
还要注意,h.i == 1 ? true : false
是同义词,只要h.i == 1
就足够了。