繁体   English   中英

用于检查变量是否等于可变参数之一的可变参数宏

[英]Variadic macro for checking if variable equals one of variadic arguments

我目前正在使用一个类似 WebGL 的 OpenGL 包装器,这涉及验证参数是否实际有效。 问题,或多或少,是 OpenGL 有一吨,我没有夸大某些函数的有效参数。 (一个天真的条件的图像(如果你感兴趣的话,可以是glTexImage2D internalformat glTexImage2D常量。我真的为其中一些写了一个 JS 表解析器/条件生成器)来说明我的观点。这是一个assert ......)

这种检查的逻辑很简单:

bool check(const unsigned int var)
{
    return var == CONSTANT_1 || var == CONSTANT_2 || var == CONSTANT_...;
}

但是,根据上面的示例,这最多可以扩展 84 个可能的常量,这是......是的。 而且我完全意识到宏不会以荒谬的数量减少这一点,但它仍然会有所作为,而且我觉得它也会更干净。 更不用说具有不同运算符的类似方式的其他宏的可能性。

所以我的想法是使用宏。 毕竟,使用std::initializer_list``, std::vector , std::array` 或其他一些容器,在运行时进行此检查是微不足道的,但是由于所有这些常量在编译时都是已知的,因此我感觉好像这是不必要的。

由于可能的常量的数量是可变的,我认为没有办法不使用可变参数宏。 然而我不知道我将如何实现这一点。 我想到的一种可能的方法是根据参数的数量(类似于 this )重载宏,但这似乎不必要地复杂。

本质上,我正在寻找一个可以满足以下要求的宏:

MACRO(var, CONSTANT_1, CONSTANT_2, CONSTANT_3)

扩展到

var == CONSTANT_1 || var == CONSTANT_2 || var == CONSTANT_3

具有任意数量的常量(重要!和困难的部分)。

您可能想使用 C++17折叠表达式

template<class... Args>
bool check(const unsigned int var, const Args&... args)
{
  return ((var == args) || ...);
}

然后你可以调用这样的东西:

check(var, CONSTANT_1, CONSTANT_2, CONSTANT_3);

您不需要宏。 如果constexpr std::array有常量,则可以按如下方式使用std::any_of

#include <algorithm>  // std::any_of

inline static constexpr std::array<unsigned int, 2> arr_of_const{ CONSTANT_1, CONSTANT_2 };

consteval bool check(unsigned int var)
{
    return std::any_of(arr_of_const.cbegin(), arr_of_const.cend(), [var](auto ele) { return var == ele; });
}

这里不需要使用宏,一个简单的函数和有效值数组就可以完成这项工作:

#include <array>
#include <algorithm>
#include <iostream>

constexpr int CONSTANT_1 = 0;
constexpr int CONSTANT_2 = 1;
constexpr int CONSTANT_3 = 2;
constexpr int CONSTANT_4 = 3;

constexpr std::array<int, 3 > VALID_CONSTANTS = { CONSTANT_1, CONSTANT_2, CONSTANT_3 };

template <size_t N>
constexpr bool check(int value, const std::array<int, N>& values)
{
    return std::find(values.begin(), values.end(), value) != values.end();
}

int main()
{
    std::cout << check(CONSTANT_1, VALID_CONSTANTS) << "\n";
    std::cout << check(CONSTANT_4, VALID_CONSTANTS) << "\n";
}

通过一个小的修改,代码在编译时被完全评估:

#include <array>
#include <algorithm>
#include <iostream>

constexpr int CONSTANT_1 = 0;
constexpr int CONSTANT_2 = 1;
constexpr int CONSTANT_3 = 2;
constexpr int CONSTANT_4 = 3;

struct VALID_CONSTANTS
{
    static constexpr std::array<int, 3 > values = { CONSTANT_1, CONSTANT_2, CONSTANT_3 };
};

template <typename Values>
constexpr bool check(int value)
{
    return std::find(Values::values.begin(), Values::values.end(), value) != Values::values.end();
}

int main()
{
    std::cout << check<VALID_CONSTANTS>(CONSTANT_1) << "\n";
    std::cout << check<VALID_CONSTANTS>(CONSTANT_4) << "\n";
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM