检查C++中是否只有一个字符串变量不为nullptr
我有三个LPCWSTR
字符串变量,称为A
,。检查C++中是否只有一个字符串变量不为nullptr
我从另一个函数中指定它们,如果出现错误,有时可能返回nullptr
。像这样:
A = MyFunc();
B = MyFunc();
C = MyFunc();
现在,对一些东西用这些变量,我需要检查,如果只有这些变量中的一个不nullptr
(只有一个变量被分配)。
我想这个做自己喜欢:
if ((A == nullptr) && (B == nullptr) && (C <> nullptr)) {}
有关如何做到这一点,欢迎任何想法。
足够容易做:
int numSet = 0;
A = MyFunc(); if (A != nullptr) numSet++;
B = MyFunc(); if (B != nullptr) numSet++;
C = MyFunc(); if (C != nullptr) numSet++;
if (numSet == 1) // only one is set
你也可以封装用辅助函数的行为:
LPCWSTR MyFuncWithCount(int &countSetProperly) {
LPCWSTR retVal = MyFunc();
if (retVal != nullptr) countSetProperly++;
return retVal;
}
int numSet = 0;
A = MyFuncWithCount(numSet);
B = MyFuncWithCount(numSet);
C = MyFuncWithCount(numSet);
if (numSet == 1) // only one is set
下一步从那里将使用基于范围的循环连同支撑在它列表,按照下列完整的程序:
#include <iostream>
#include <vector>
typedef void * LPCWSTR; // Couldn't be bothered including Windows stuff :-)
int main() {
// Only set two for test purposes.
LPCWSTR A = nullptr, B = nullptr, C = nullptr;
LPCWSTR D = &A, E = nullptr, F = &A;
int numSet = 0;
for (const auto &pointer: {A, B, C, D, E, F})
if (pointer != nullptr)
numSet++;
std::cout << "Count is " << numSet << std::endl;
}
或者你可以通过使用lambda函数拥抱在其所有的荣耀现代C++,按以下操作:
#include <iostream>
#include <vector>
typedef void * LPCWSTR; // Couldn't be bothered including Windows stuff :-)
int main() {
// Only set two for test purposes.
LPCWSTR A = nullptr, B = nullptr, C = nullptr;
LPCWSTR D = &A, E = nullptr, F = &A;
int numSet = 0;
[&numSet](const std::vector<LPCWSTR> &pointers) {
for (const auto &pointer: pointers)
if (pointer != nullptr)
numSet++;
} (std::vector<LPCWSTR>{A,B,C,D,E,F});
std::cout << "Count is " << numSet << std::endl;
}
这可能但是,你的具体情况矫枉过正:-)
谢谢!这起泡沫很好。不过,我也会看看异或。 :-) – Blueeyes789
难道你不能使用'std :: initializer_list'而不是'std :: vector'来避免分配。那和......'std :: count'。 –
我以前从来没有在C++中见过立即调用的lambda表达式...为什么不是'for(const auto&pointer:{A,B,C,D,E,F}){...'? –
这里有一个简单的方法:
每个int not_null = 0;
not_null += A != nullptr;
not_null += B != nullptr;
not_null += C != nullptr;
if (not_null == 1) {
/* Do stuff */
}
检查是nullptr
和递增计数,如果事实并非如此。如果计数最终以1
的形式出现,请执行您的操作。
与标准,你可以这样做:
const auto vars = {A, B, C}; // Create initializer list.
const bool onlyOneNotNull =
(std::count(vars.begin(), vars.end(), nullptr) == (vars.size() - 1);
// then you may use find_if to retrieve the non null variable.
在C++中,为了与C向后兼容,关系运算符的返回值是int
等于0
或1
。所以,你可以这样做:
if ((a != nullptr) + (b != nullptr) + (c != nullptr) == 1)
如果你想使用逻辑运算符仅作为逻辑运算符,也有析取范式与合取范式,尽管有更多的操作。
if ((a && !b && !c) || (!a && b && !c) || (!a && !b && c))
if ((a || b || c) && (!a || !b) && (!a || !c) && (!b || !c))
前者不难在这个简单的例子看,相比于大多数其他的解决方案,但它会很快得到太冗长,如果有更多的可能的解决方案。
您也可以将它们粘贴在任何容器中,例如std::array<LPCWSTR, 3>
,以及std::count(pointers.begin(), pointers.end(), nullptr)
(如Jarod42建议的那样)。
我不是一般使用以下技术的狂热粉丝,但是您可以使用这样一个事实,即任何指标ptr
!!ptr
对空指针评估为0,对于写空指针评估为1
if (!!A + !!B + !!C == 1) {
...
}
作为一种密集的方式来得到这个工作。它基本上与@ Davislor的解决方案相同,但是具有更紧凑的“test if null”检查。
这种方法几乎不像已接受的方法那么好,读起来也比较麻烦,但根据你的读者和谁在阅读代码,它可能会很好地实现这个技巧。
如果这是代码高尔夫你会赢!我认为我不会那样写,但它很聪明。 – Davislor
难道你不能连锁'xor',然后否定结果吗?像'!(A^B^C)'这样的东西。 '^'是按位,但它可能工作?只是吐球。 – Carcigenicate
@Carcigenicate谢谢!但是我从来没有在C++中使用'xor' :-(无论如何都会试一试。 – Blueeyes789
我们可以假设你不在乎哪一个是空的,只要其中一个是空的? – user4581301