可能重复:
C++ 将一堆值与给定值进行比较
我需要在 C++ 中的 for 循环中检查是否相等,但是循环需要为 x 等于多种可能性工作。
例如,现在我有类似的东西:
if(x==a || x==b || x==c || x==d || x==e || x==f || x==g || x==h)
{
//loop body
}
但是对于我拥有的数字,它看起来很乱,我想知道是否有一种简写方式来表达“如果(x ==(其中任何一个))”,或者是否将它们全部写出来是唯一的选择。
谢谢!
可能重复:
C++ 将一堆值与给定值进行比较
我需要在 C++ 中的 for 循环中检查是否相等,但是循环需要为 x 等于多种可能性工作。
例如,现在我有类似的东西:
if(x==a || x==b || x==c || x==d || x==e || x==f || x==g || x==h)
{
//loop body
}
但是对于我拥有的数字,它看起来很乱,我想知道是否有一种简写方式来表达“如果(x ==(其中任何一个))”,或者是否将它们全部写出来是唯一的选择。
谢谢!
谢谢你的问题,现在我找到了一个解决方案(我敢说是一个优雅的解决方案),我会自己使用它。
与使用 std::find 的解决方案不同:a ) 是否会在编译时展开到 N 次比较 b) 适用于 X 可以与之比较的任何类型
struct TagAnyOf {};
template <typename... Args>
std::tuple <TagAnyOf, Args...> AnyOf (Args&&... args)
{
return std::tuple <TagAnyOf, Args...> (TagAnyOf(), std::forward<Args>(args)...);
}
template <class X, class Tuple, size_t Index, size_t ReverseIndex>
struct CompareToTuple
{
static bool compare (const X& x, const Tuple& tuple)
{
return x == std::get<Index> (tuple) || CompareToTuple<X, Tuple, Index+1, ReverseIndex-1>::compare (x, tuple);
}
};
template <class X, class Tuple, size_t Index>
struct CompareToTuple <X, Tuple, Index, 0>
{
static bool compare (const X& x, const Tuple& tuple)
{
return false;
}
};
template <typename X, typename... Args>
bool operator == (const X& x, const std::tuple<TagAnyOf, Args...>& any)
{
typedef std::tuple <TagAnyOf, Args...> any_of_type;
return CompareToTuple <X, any_of_type, 1, std::tuple_size<any_of_type>::value-1>::compare (x, any);
}
用法
int main()
{
int x = 1;
if (x == AnyOf (1, 2, 3, 4))
{
std::cout << "Yes!" << std::endl;
}
else
{
std::cout << "No!" << std::endl;
}
if (x == AnyOf (4, 3, 2, 1))
{
std::cout << "Yes!" << std::endl;
}
else
{
std::cout << "No!" << std::endl;
}
if (x == AnyOf (2, 3, 4, 5))
{
std::cout << "Yes!" << std::endl;
}
else
{
std::cout << "No!" << std::endl;
}
return 0;
}
考虑使用一个带有 initializer_list 的函数(这是一个 c++11 特性)。
第一个参数将是左侧值(在您的情况下为 x),其余参数将是右侧值。
这是一个使用模板完成任务的示例。
#include <iostream>
#include <cstdlib>
#include <algorithm>
template<class T>
bool Test(T const& test, std::initializer_list<T> const& values){
return std::find(std::begin(values), std::end(values), test) != std::end(values);
}
int main(){
char var1 = 'a';
char var2 = 'a';
char var3 = 'b';
char var4 = 'c';
char var5 = 'd';
if (Test<char>(var1,{var2,var3,var4,'o',var5})){
std::cout << "true. at least one is equivelent" << std::endl;
}else{
std::cout << "false. none are equivelent" << std::endl;
}
if (Test<char>(var1,{var3,var4,var5})){
std::cout << "true. at least one is equivelent" << std::endl;
}else{
std::cout << "false. none are equivelent" << std::endl;
}
return EXIT_SUCCESS;
}
如果您使用类执行此操作,请确保重载 '!=' 运算符。
编辑:错误已修复。GManNickG 指出
我想知道是否有一种简写方式来表达“如果(x ==(其中任何一个))”
是的,该标准为您提供std::find并std::find_if准确回答了这个问题:
int a=3,b=5,c=6,d=7;
std::array<int,4> vals{{a,b,c,d}}; // or std::vector
int x=5;
bool foundit= (end(vals) != std::find_if(begin(vals), end(vals),x );
你会需要
#include <array>
#include <algorithm>
您也可以使用std::initializer_list<int> booleans{a,b,c,d};代替vector或array
如果您的情况更复杂,您可以使用 find_if:
bool foundit= (end(vals) !=
std::find_if(begin(vals), end(vals),
[&x](const int &v){return v*(v+x)<x;}));