我有以下C++代码:
Some_class * temp1 = findTemp1(...); // returns NULL or a valid pointer
Some_class * temp2 = findTemp2(...); // returns NULL or a valid pointer
Some_class * temp3 = findTemp3(...); // returns NULL or a valid pointer
Run Code Online (Sandbox Code Playgroud)
现在我想计算其中有多少返回了一个有效的指针(0,1,2或3).
我能想到的唯一方法就是逐一测试它们:
int count = 0;
if (temp1)
count++;
if (temp2)
count++;
if (temp3)
count++;
Run Code Online (Sandbox Code Playgroud)
对于三分球,它并不是太糟糕,但它不能很好地扩展.假设我没有重新定义findTempN函数(可能在计数器中传递),是否有更有效的方法?
非常感谢您的快速回复!不,我不会改变代码,我只是想知道我的其他选择是什么.我也意识到如果我使用这样的不同文字来定义3个指针,我就不能要求"可扩展"的东西.当然,我没有想到你回复的事情:)
Jon*_*Jon 11
好吧,因为这是C++,我们可以为追求简洁而疯狂......例如:
int count = !!temp1 + !!temp2 + !!temp3;
Run Code Online (Sandbox Code Playgroud)
更新:我可能欠伊万一个关于这里发生了什么的解释.
假设temp是任何类型的指针,!temp强制指针值的强制bool(我们想要这样做)并否定结果(这是我们不想要的副作用).这导致true如果指针是空,false如果指针不为空,这是什么,我们倒是想相反.所以我们!在前面添加另一个来再次否定结果.
这使我们添加三个bool值来强制它们int并执行添加,于是我们得到了最终结果.
您可能会发现更容易理解完全等效的内容
int count = (bool)temp1 + (bool)temp2 + (bool)temp3;
Run Code Online (Sandbox Code Playgroud)
我没有使用,因为打字!!比三个字符短(bool)(注意:您可能认为这是一个很好的技巧,但在编写代码时,根据您需要键入的字符数做出决定是一个非常糟糕的主意).
这个故事的寓意是,做这种事情可以被称为聪明或残暴,取决于你问的是谁 - 但在C++中,传统上对暴行有很高的容忍度.
需要注意的是,如果指针是在某些类型的集合,开始用的,你可以写更好看的代码使用std::count_if,例如:
bool isNotNull(void* ptr) {
return ptr != 0;
}
std::vector<Some_class*> vec;
vec.push_back(temp1);
vec.push_back(temp2);
vec.push_back(temp3);
int count = std::count_if(vec.begin(), vec.end(), isNotNull);
Run Code Online (Sandbox Code Playgroud)
或者,非常巧妙地MSalters的意见建议,你可以失去了isNotNull通过计算该指针函数是 0和所有指针的数减去这一点-但对于这一点,你需要以某种方式知道这是个什么(如果它们在a vector)中很容易:
int count = vec.size() - std::count(vec.begin(), vec.end(), 0);
Run Code Online (Sandbox Code Playgroud)