如何检查参数包在执行命令中是否具有确切类型
How to check if parameter pack has exact types in an exect order
我有一个函数 checkTO
,它将一个函数包作为参数,我想知道这个包是否包含 int
、char
和 bool
类型以及按照这个特定的顺序,但同时它们可以放在任何地方。其他相同类型的参数是允许的,我只需要知道这个顺序中的这 3 个是否存在。
我有这个例子可以完成这项工作。
#include <iostream>
static bool foundInt = false;
static bool foundChar = false;
static bool foundBool = false;
static bool hasTO = false;
void check() {
}
template <typename T>
void check(T value) {
if (hasTO) {
return;
}
if (foundInt && foundChar && foundBool) {
hasTO = true;
return;
}
if (!foundInt || !foundChar) {
hasTO = false;
return;
}
hasTO = std::is_same<T, bool>::value;
}
template <typename First, typename... Rest>
void check(First firstValue, Rest... rest) {
if (!foundInt) {
if (std::is_same<First, int>::value) {
foundInt = true;
}
check(rest...);
} else if (!foundChar) {
if (std::is_same<First, char>::value) {
foundChar = true;
} else {
// args have to be in a special order
if (!std::is_same<First, int>::value) {
foundInt = false;
}
}
check(rest...);
} else if (!foundBool) {
if (std::is_same<First, bool>::value) {
foundBool = true;
hasTO = true;
} else {
// args have to be in a special order
foundInt = false;
foundChar = false;
}
check(rest...);
}
check(rest...);
}
template <typename... T_values>
bool checkTO(const T_values&... args) {
foundInt = false;
foundChar = false;
foundBool = false;
hasTO = false;
check(args...);
return hasTO;
}
int main()
{
int a = 1;
char b = 'c';
bool c = true;
float d = 1.1;
float d1 = 1.1;
float d2 = 1.2;
std::cout << "TRUE1: " << checkTO() << std::endl;
std::cout << "TRUE1: " << checkTO(a, b, c) << std::endl;
std::cout << "TRUE2: " << checkTO(a, a, b, c) << std::endl;
std::cout << "TRUE3: " << checkTO(a, a, b, c, c) << std::endl;
std::cout << "TRUE4: " << checkTO(d, a, b, c, c) << std::endl;
std::cout << "TRUE5: " << checkTO(a, b, d1, a, b, c, d2) << std::endl;
std::cout << "TRUE6: " << checkTO(d1, d2, a, a, a, b, c) << std::endl;
std::cout << "TRUE7: " << checkTO(a, b, c, d1, d2, a, a, b, a, c) << std::endl;
std::cout << "FALSE1: " << checkTO(c, a, b) << std::endl;
std::cout << "FALSE2: " << checkTO(b, c, a) << std::endl;
std::cout << "FALSE3: " << checkTO(d1, a, b) << std::endl;
std::cout << "FALSE4: " << checkTO(a, b, d1, c) << std::endl;
}
输出:
TRUE1: 0
TRUE1: 1
TRUE2: 1
TRUE3: 1
TRUE4: 1
TRUE5: 1
TRUE6: 1
TRUE7: 1
FALSE1: 0
FALSE2: 0
FALSE3: 0
FALSE4: 0
我真的很讨厌这个解决方案,因为它不可扩展(如果我需要检查 44 个参数怎么办?)和全局变量。有更聪明的方法吗?
template<typename...T> struct check;
template<typename A, typename...B> struct check<A,B...> {
static constexpr bool pass = check<B...>::pass;
};
template<typename...R> struct check<int,char,bool,R...> {
static constexpr bool pass = true;
};
template<> struct check<> {
static constexpr bool pass = false;
};
template<typename... T>
constexpr bool check_this(T...) { return check<T...>::pass; }
这使用 template struct
和一些模板特化:
- 参数包 "iterates" 中的一个
- 一个在找到请求的序列时匹配
- 与 "base case" 匹配的一个(例如,未找到匹配项)
Live example on ideone 使用您的 main(并将我的 check_this
重命名为 checkTO
)。通过了除第一个之外的所有测试...为什么 checkTO()
return 为真??
我有一个函数 checkTO
,它将一个函数包作为参数,我想知道这个包是否包含 int
、char
和 bool
类型以及按照这个特定的顺序,但同时它们可以放在任何地方。其他相同类型的参数是允许的,我只需要知道这个顺序中的这 3 个是否存在。
我有这个例子可以完成这项工作。
#include <iostream>
static bool foundInt = false;
static bool foundChar = false;
static bool foundBool = false;
static bool hasTO = false;
void check() {
}
template <typename T>
void check(T value) {
if (hasTO) {
return;
}
if (foundInt && foundChar && foundBool) {
hasTO = true;
return;
}
if (!foundInt || !foundChar) {
hasTO = false;
return;
}
hasTO = std::is_same<T, bool>::value;
}
template <typename First, typename... Rest>
void check(First firstValue, Rest... rest) {
if (!foundInt) {
if (std::is_same<First, int>::value) {
foundInt = true;
}
check(rest...);
} else if (!foundChar) {
if (std::is_same<First, char>::value) {
foundChar = true;
} else {
// args have to be in a special order
if (!std::is_same<First, int>::value) {
foundInt = false;
}
}
check(rest...);
} else if (!foundBool) {
if (std::is_same<First, bool>::value) {
foundBool = true;
hasTO = true;
} else {
// args have to be in a special order
foundInt = false;
foundChar = false;
}
check(rest...);
}
check(rest...);
}
template <typename... T_values>
bool checkTO(const T_values&... args) {
foundInt = false;
foundChar = false;
foundBool = false;
hasTO = false;
check(args...);
return hasTO;
}
int main()
{
int a = 1;
char b = 'c';
bool c = true;
float d = 1.1;
float d1 = 1.1;
float d2 = 1.2;
std::cout << "TRUE1: " << checkTO() << std::endl;
std::cout << "TRUE1: " << checkTO(a, b, c) << std::endl;
std::cout << "TRUE2: " << checkTO(a, a, b, c) << std::endl;
std::cout << "TRUE3: " << checkTO(a, a, b, c, c) << std::endl;
std::cout << "TRUE4: " << checkTO(d, a, b, c, c) << std::endl;
std::cout << "TRUE5: " << checkTO(a, b, d1, a, b, c, d2) << std::endl;
std::cout << "TRUE6: " << checkTO(d1, d2, a, a, a, b, c) << std::endl;
std::cout << "TRUE7: " << checkTO(a, b, c, d1, d2, a, a, b, a, c) << std::endl;
std::cout << "FALSE1: " << checkTO(c, a, b) << std::endl;
std::cout << "FALSE2: " << checkTO(b, c, a) << std::endl;
std::cout << "FALSE3: " << checkTO(d1, a, b) << std::endl;
std::cout << "FALSE4: " << checkTO(a, b, d1, c) << std::endl;
}
输出:
TRUE1: 0
TRUE1: 1
TRUE2: 1
TRUE3: 1
TRUE4: 1
TRUE5: 1
TRUE6: 1
TRUE7: 1
FALSE1: 0
FALSE2: 0
FALSE3: 0
FALSE4: 0
我真的很讨厌这个解决方案,因为它不可扩展(如果我需要检查 44 个参数怎么办?)和全局变量。有更聪明的方法吗?
template<typename...T> struct check;
template<typename A, typename...B> struct check<A,B...> {
static constexpr bool pass = check<B...>::pass;
};
template<typename...R> struct check<int,char,bool,R...> {
static constexpr bool pass = true;
};
template<> struct check<> {
static constexpr bool pass = false;
};
template<typename... T>
constexpr bool check_this(T...) { return check<T...>::pass; }
这使用 template struct
和一些模板特化:
- 参数包 "iterates" 中的一个
- 一个在找到请求的序列时匹配
- 与 "base case" 匹配的一个(例如,未找到匹配项)
Live example on ideone 使用您的 main(并将我的 check_this
重命名为 checkTO
)。通过了除第一个之外的所有测试...为什么 checkTO()
return 为真??