有没有办法缩短此if
声明的条件?
int x;
if (x != 3 && x != 8 && x != 87 && x != 9){
SomeStuff();
}
我想的是这样的事情:
if (x != 3, 8, 87, 9) {}
但是我试过了,但它不起作用。我是否只需要将其全部写出来?
答案 0 :(得分:43)
如果您想知道整数是否在给定的整数集中,请使用std::set
:
std::set<int> accept { 1, 4, 6, 8, 255, 42 };
int x = 1;
if (!accept.count(x))
{
// ...
}
答案 1 :(得分:31)
为了完整起见,我会提供一个开关:
switch (x) {
case 1:
case 2:
case 37:
case 42:
break;
default:
SomeStuff();
break;
}
虽然这非常详细,但它只评估x
一次(如果它是一个表达式),并且可能生成任何解决方案的最有效代码。
答案 2 :(得分:28)
这是我使用可变参数模板的解决方案。运行时性能与手动编写x != 3 && x != 8 && x != 87 && x != 9
一样高效。
template <class T, class U>
bool not_equal(const T& t, const U& u) {
return t != u;
}
template <class T, class U, class... Vs>
bool not_equal(const T& t, const U& u, const Vs... vs) {
return t != u && not_equal(t, vs...);
}
int main() {
std::cout << not_equal( 3, 3, 8, 87, 9) << std::endl;
std::cout << not_equal( 8, 3, 8, 87, 9) << std::endl;
std::cout << not_equal(87, 3, 8, 87, 9) << std::endl;
std::cout << not_equal( 9, 3, 8, 87, 9) << std::endl;
std::cout << not_equal(10, 3, 8, 87, 9) << std::endl;
}
答案 3 :(得分:14)
这个怎么样:
#include <iostream>
#include <initializer_list>
#include <algorithm>
template <typename T>
bool in(const T t, const std::initializer_list<T> & l) {
return std::find(l.begin(), l.end(), t) != l.end();
}
int main() {
std::cout << !in(3, {3, 8, 87, 9}) << std::endl;
std::cout << !in(87, {3, 8, 87, 9}) << std::endl;
std::cout << !in(10, {3, 8, 87, 9}) << std::endl;
}
或重载operator!=
:
template<typename T>
bool operator!=(const T t, const std::vector<T> & l) {
return std::find(l.begin(), l.end(), t) == l.end();
}
int main() {
std::cout << ( 3!=std::vector<int>{ 3, 8, 87, 9}) << std::endl;
std::cout << ( 8!=std::vector<int>{ 3, 8, 87, 9}) << std::endl;
std::cout << (10!=std::vector<int>{ 3, 8, 87, 9}) << std::endl;
}
不幸的是目前parsers do not like to have initializer_list
as argument of operators,所以在第二个解决方案中无法摆脱std::vector<int>
。
答案 4 :(得分:5)
如果您不想一遍又一遍地重复此条件,请使用宏。
#include <iostream>
#define isTRUE(x, a, b, c, d) ( x != a && x != b && x != c && x != d )
int main()
{
int x(2);
std::cout << isTRUE(x,3,8,87,9) << std::endl;
if ( isTRUE(x,3,8,87,9) ){
// SomeStuff();
}
return 0;
}
答案 5 :(得分:3)
如果数字不是&#34; 1,2,3,4&#34;而是随机数的随机整数,然后你可以将这些数字放在数据结构中(例如std::vector
),然后使用循环遍历该数组(如下所示,std :: find是一个现成的选项。)
例如:
#include <algorithm>
int x;
std::vector<int> checknums;
// fill the vector with your numbers to check x against
if (std::find(checknums.begin(), checknums.end(), x) != checknums.end()){
DoStuff();
}
答案 6 :(得分:3)
int A[]={3, 8, 87, 9};
int x;
if (std::find(A, A+4, x)==A+4) SomeStuff();
答案 7 :(得分:3)
请注意,许多C ++程序员都非常不喜欢使用宏,因为宏非常强大,并且如果创建不当,就有可能令人沮丧。但是,如果正确和智能地创建和使用它们可以节省大量时间。我没有看到另一种方法来获得所请求的语法和代码空间,每次比较类似于您请求的内容,而不会影响程序使用的效率,代码空间或内存。您的目标是拥有一条捷径,此处提供的大多数其他解决方案都比您最初想要缩短的时间长。假设您正在比较整数:
,下面是安全地执行此操作的宏#pragma once
int unused;
#define IFNOTIN2(x, a, b) \
if (unused = (x) && unused != (a) && unused != (b))
#define IFNOTIN3(x, a, b, c) \
if (unused = (x) && unused != (a) && unused != (b) && unused != (c))
#define IFNOTIN4(x, a, b, c, d) \
if (unused = (x) && unused != (a) && unused != (b) && unused != (c) && unused != (d))
#define IFNOTIN5(x, a, b, c, d, e) \
if (unused = (x) && unused != (a) && unused != (b) && unused != (c) && unused != (d) && unused != (e))
以下是使用上述宏之一的经过测试的示例:
#include <iostream>
#include "macros.h"
int main () {
std::cout << "Hello World\n";
for (int i = 0; i < 100; i ++) {
std::cout << i << ": ";
IFNOTIN4 (i, 7, 17, 32, 87) {
std::cout << "PASSED\n";
} else {
std::cout << "FAILED\n";
}
}
std::cin.get();
return 0;
}
请注意,宏应该放在一个包含在您需要使用它们的位置的头文件中。如果您已经使用名为&#39; unused&#39;的变量,则代码将无法编译。在其他地方的代码中或尝试使用这些宏来比较整数以外的东西。我确定你可以扩展宏来处理其他类型的数据,如果有必要的话。
通过在所有输入周围使用括号来保留操作顺序,并在比较之前将值保存到变量中,以防止多次执行CPU密集型代码。