检查变量是否等于这些值中的任何一个

Pyt*_*hon 0 c++

在 C++ 中,有没有办法查看变量是否等于其中一个值?现在我必须做

if (fExt == "zip" | fExt == "7z" | fExt == "gz" | fExt == "tar")
    {
        //do something
    }
Run Code Online (Sandbox Code Playgroud)

然而,有没有更有效的方法呢?

ypn*_*nos 5

一组示例:

if (std::set<std::string>{"zip", "7z", "gz", "tar"}.count(fExt)) {
     std::cerr << "yes" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

请注意,std::set::count()返回 0 或 1 并提供与std::set::contains()仅在 C++20 中引入的功能相同的有效功能。

这还不错,因为它可能会跳过一些比较。考虑到设置和拆卸集的额外工作,它仍然不会更有效率。但是如果你的代码被更频繁地调用,通过重用集合会变得更好:

static const std::set<std::string> extensions{"zip", "7z", "gz", "tar"};
if (extensions.count(fExt)) {
    std::cerr << "yes" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

是否会比进行四个字符串比较更有效尚有争议,但它可能也不会更糟;并且可能更容易维护。

您也可以使用unordered_set,但是对于像您这样的少量元素,它会进行更多不必要的计算。


cig*_*ien 5

如果你可以使用 c++17,我建议使用折叠表达式:

template<typename T, typename ...Opts>
bool any_of(T val, Opts ...opts)
{
    return (... || (val == opts));
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样使用:

if (any_of(fExt, "zip", "7z", "gz", "tar"))
{
  // ...
}
Run Code Online (Sandbox Code Playgroud)

您应该将此函数放入您自己的命名空间中,以避免与标头中的任何可能的std::any_of混淆<algorithm>

  • 我会使用不同的名称以避免与 `std::any_of` 混淆(顺便说一句,这里也可以使用它) (3认同)
  • @idclev463035818 实际上,我认为“any_of”是正确的名称。无论如何,`std::any_of` 应该始终是合格的。使用 std::any_of 并不理想,因为需要创建一个单独的范围。 (2认同)