检查 C++ 中是否只有一个字符串变量不是 nullptr
Check if only one string variable is not nullptr in C++
我有三个 LPCWSTR
字符串变量,名为 A
、B
、C
。
我正在从另一个函数分配它们,如果出现问题,有时可以 return nullptr
。像这样:
A = MyFunc();
B = MyFunc();
C = MyFunc();
现在,对于一些带有这些变量的东西,我需要检查这些变量中是否只有一个不是 nullptr
(只分配了一个变量)。
我自己尝试这样做:
if ((A == nullptr) && (B == nullptr) && (C <> nullptr)) {}
欢迎提出有关如何执行此操作的任何想法。
这是一种简单的方法:
int not_null = 0;
not_null += A != nullptr;
not_null += B != nullptr;
not_null += C != nullptr;
if (not_null == 1) {
/* Do stuff */
}
检查每个是否 nullptr
,如果不是则递增计数。如果最后计数结果为 1
,请执行您的操作。
很容易做到:
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
下一步将使用 基于范围的 for 循环 结合 支撑初始化列表, 根据以下是完整的程序:
#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;
}
然而,对于您的特定情况,这可能有点矫枉过正 :-)
对于 std,你可以这样做:
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 向后兼容,关系运算符的 return 值是 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" 检查。
这种方法的扩展性不如公认的方法那么好,而且阅读起来也比较棘手,但根据您的听众和阅读代码的人的不同,它可能会很好地发挥作用。
我有三个 LPCWSTR
字符串变量,名为 A
、B
、C
。
我正在从另一个函数分配它们,如果出现问题,有时可以 return nullptr
。像这样:
A = MyFunc();
B = MyFunc();
C = MyFunc();
现在,对于一些带有这些变量的东西,我需要检查这些变量中是否只有一个不是 nullptr
(只分配了一个变量)。
我自己尝试这样做:
if ((A == nullptr) && (B == nullptr) && (C <> nullptr)) {}
欢迎提出有关如何执行此操作的任何想法。
这是一种简单的方法:
int not_null = 0;
not_null += A != nullptr;
not_null += B != nullptr;
not_null += C != nullptr;
if (not_null == 1) {
/* Do stuff */
}
检查每个是否 nullptr
,如果不是则递增计数。如果最后计数结果为 1
,请执行您的操作。
很容易做到:
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
下一步将使用 基于范围的 for 循环 结合 支撑初始化列表, 根据以下是完整的程序:
#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;
}
然而,对于您的特定情况,这可能有点矫枉过正 :-)
对于 std,你可以这样做:
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 向后兼容,关系运算符的 return 值是 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" 检查。
这种方法的扩展性不如公认的方法那么好,而且阅读起来也比较棘手,但根据您的听众和阅读代码的人的不同,它可能会很好地发挥作用。