Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 检查枚举值范围的快速方法_C++_Enums - Fatal编程技术网

C++ 检查枚举值范围的快速方法

C++ 检查枚举值范围的快速方法,c++,enums,C++,Enums,是否有一种synatx古怪的快速/单行方式允许您检查枚举是否具有指定的值 例如: enum fruit_and_vegetables { apples, pears, tomatoes, cucumbers } int main() { fruit_and_vegetables something = apples; if( something = {apples, pears} ) // <-- this here cou

是否有一种synatx古怪的快速/单行方式允许您检查枚举是否具有指定的值

例如:

enum fruit_and_vegetables
{
    apples,
    pears,
    tomatoes,
    cucumbers
}

int main()
{
    fruit_and_vegetables something = apples;
    if( something = {apples, pears} ) // <-- this here
        cout << "something is fruit." << endl;
    else
        cout "something is a vegetable." << endl;
    return 0;
}
列举水果和蔬菜
{
苹果,
梨,
西红柿,
黄瓜
}
int main()
{
水果和蔬菜某物=苹果;

if(something={apples,pears})/
if(something
我不知道,但您可以做的是将值
2^I
分配给枚举成员。例如:

enum fruit_and_vegetables
{
    apples    = (1<<0),
    pears     = (1<<1),
    tomatoes  = (1<<2),
    cucumbers = (1<<3)
    // ...
}
列举水果和蔬菜
{

苹果=(1还有另一种方法扩展了@bitmask的答案:

假设您可以检查固定数量的条件。因此,您可以使用额外的LUT,而不是对
水果和蔬菜
枚举的值使用位掩码(这将限制您的单词大小):

enum fruit_and_vegetables {
    apples  = 0,
    pears,
    tomatoes,
    cucumbers
}

enum qualifs {
   is_fruit = 1,
   is_sweet = 1<<1,
   is_round = 1<<2,
   is_tasty = 1<<3
}

const qualifs qualifs_LUT[] = { // can be generated
   is_fruit | is_sweet | is_round, // apple
    ...
};

<强>编辑< /强>:另一个有趣的方法。考虑(再次)@位掩码:方法。它依赖于2的幂。但是素数如何?它们生长得慢得多,因此,通过将素数分配给枚举值,可以假定更多的值,假设产品不会溢出:

enum fruit_and_vegetables {
    apples  = 2,
    pears = 3,
    tomatoes = 5,
    cucumbers = 7
}

if ((apples * pears * tomatoes) % tomatoes == 0)
     printf("it's tasty!");

此选项限制了控件集中的项目数。

您可以编写帮助器模板,帮助您实现所需的语法:

enum fruit_and_vegetables
{
    nothing,
    apples,
    pears,
    tomatoes,
    cucumbers
};

// helper template
typedef fruit_and_vegetables fav;
template<fav v1 = nothing, fav v2 = nothing, fav v3 = nothing, fav v4 = nothing,
  fav v5 = nothing, fav v6 = nothing, fav v7 = nothing, fav v8 = nothing>
bool check_equal( fruit_and_vegetables value )
{
    return ( value == v1 || value == v2 || value == v3 || value == v4 ||
             value == v5 || value == v6 || value == v7 || value == v8 );
}

// usage
int main()
{
    fruit_and_vegetables something = apples;
    if( check_equal<apples, pears>(something) )
        std::cout << "something is fruit." << std::endl;
    else
        std::cout << "something is a vegetable." << std::endl;

    return 0;
}
列举水果和蔬菜
{
没有什么,
苹果,
梨,
西红柿,
黄瓜
};
//辅助模板
typedef水果和蔬菜fav;
模板
布尔检查(水果和蔬菜价值)
{
返回值(value==v1 | | value==v2 | | value==v3 | | value==v4||
值==v5 | |值==v6 | |值==v7 | |值==v8);
}
//用法
int main()
{
水果和蔬菜某物=苹果;
如果(检查是否等于(某物))

std::cout处理较大的未分类产品集:

enum fruit_and_vegetables
{
    apples,
    pears,
    tomatoes,
    cucumbers,
    MAX_VALUE
};

vector<bool> arguablyVegetables(MAX_VALUE, false);
arguablyVegetables[tomatoes] = true;
arguablyVegetables[cucumbers] = true;

cout << arguablyVegetables[apples] << endl;
列举水果和蔬菜
{
苹果,
梨,
西红柿,
黄瓜,
最大值
};
向量arguablyVegetables(最大值,false);
arguablyVegetables[番茄]=真;
arguablyVegetables[黄瓜]=真;

啊,这很容易做到

template <typename T>
pair<T, fruit_and_vegetables> operator||(T t, fruit_and_vegetables v) {
    return make_pair(t, v);
}

template <typename T>
bool operator==(fruit_and vegetables lhs, pair<T, fruit_and_vegetables> rhs) {
    return lhs == rhs.second || lhs == rhs.first;
}

但是如果你使用
(苹果(梨(橙))
,这将不起作用。这可以很容易地解决,但我想保持代码简单。我相信这是目前为止唯一可以扩展到大型枚举的答案…

为什么不使用
集合
来进行逻辑运算或对多个
水果和_蔬菜
? 如果将
constexpr
放在运算符
|
和运算符
=
重载之前, 在参数和结果类型之前, 然后编译器将在编译时评估代码(无运行时开销) 如有可能;) 可以很好地扩展到更大的
a | | b | | c | | c
enum范围,您可以随意将值放在括号中

#include <set>
using std::set;

enum fruit_and_vegetables
{
    apples,
    pears,
    tomatoes,
    cucumbers
};

set< fruit_and_vegetables > operator||( fruit_and_vegetables left, fruit_and_vegetables right ) {
    set< fruit_and_vegetables > set;
    set.insert( left );
    set.insert( right );
    return set;
}

set< fruit_and_vegetables > operator||( set<fruit_and_vegetables> left, fruit_and_vegetables right ) {
    left.insert( right );
    return left;
}

set< fruit_and_vegetables > operator||( fruit_and_vegetables left, set<fruit_and_vegetables> right ) {
    right.insert( left );
    return right;
}

bool operator!=( fruit_and_vegetables lhs, set<fruit_and_vegetables> rhs ) {
    return ( rhs.find( lhs ) == rhs.end() );
}

bool operator==( fruit_and_vegetables lhs, set<fruit_and_vegetables> rhs ) {
    return !( lhs != rhs );
}

int main() {

fruit_and_vegetables fav = apples;
if ( fav == ( apples || (pears || tomatoes) ) ) cout << "match apples\n";
fav = cucumbers;
if ( fav == ( (apples || pears) || tomatoes ) ) cout << "Error! matched ghost cucumbers\n";
if ( fav != apples ) cout << "correct no match apples\n";
if ( fav == cucumbers ) cout << "default operator==(FaV, FaV) match\n";
if ( fav == ( pears || apples ) ) cout << "yummi\n";

return 0;
}
#包括
使用std::set;
列举水果和蔬菜
{
苹果,
梨,
西红柿,
黄瓜
};
设置<水果和蔬菜>操作员| |(水果和蔬菜左侧,水果和蔬菜右侧){
套装<水果和蔬菜>套装;
设置。插入(左);
设置。插入(右);
返回集;
}
设置<水果和蔬菜>操作员| |(设置左侧,水果和蔬菜右侧){
左。插入(右);
左转;
}
设置<水果和蔬菜>操作员| |(水果和蔬菜左,设置右){
右。插入(左);
返还权;
}
bool操作员!=(水果和蔬菜左侧,设置右侧){
return(rhs.find(lhs)=rhs.end());
}
布尔运算符==(水果和蔬菜左侧,设置右侧){
返回!(左侧!=右侧);
}
int main(){
水果和蔬菜fav=苹果;

如果(fav==(苹果(梨(西红柿)))不能啊是的,
“为什么我没想到这个”(C)
…但是如果枚举有中间值,而我的示例变得更复杂/未排序怎么办?西红柿和黄瓜是水果;-pNot根据SCOTUS:@Noah:
西红柿是*
而不是
西红柿是*
哇,我看到了一个非常糟糕的例子。冷静点,孩子们,每个人都有足够的
;-P
。看起来像这样评估将是“主观的和有争议的”:)-1声称西红柿好吃!j/k尽管我会说,当你开始想要从你的枚举中获得这种行为时,枚举并不是你想要的行为的合适构造。你一定是在开玩笑!西红柿真是太棒了!@bitmask:如果枚举包含70个成员呢?这种左移方法不起作用!哥们儿,既然一个类型方案在那一点上能起到更好的作用,为什么还要这么做呢?
foodplanthing
->
水果:foodplanthing
蔬菜:foodplanthing
,等等……那么访问和/或动态播放就能很容易地判断出食物是蔬菜还是水果。为什么从2开始呢?为什么不从1开始呢.
(我喜欢它!(但你可能应该让lut
常量
)@bitmask:嗯,这只是一个实现细节:)我知道,但我必须填写15个字符:)这和手工检查每个值是一样的。OP要求一个比显而易见的更快的方法。OP询问简单的语法:“oneline-way of synatx-weirdness”.有没有办法让大范围也能工作?这完全是出于兴趣,你的解决方案让我可以完美地完成我想要的!谢谢。
enum fruit_and_vegetables
{
    apples,
    pears,
    tomatoes,
    cucumbers,
    MAX_VALUE
};

vector<bool> arguablyVegetables(MAX_VALUE, false);
arguablyVegetables[tomatoes] = true;
arguablyVegetables[cucumbers] = true;

cout << arguablyVegetables[apples] << endl;
template <typename T>
pair<T, fruit_and_vegetables> operator||(T t, fruit_and_vegetables v) {
    return make_pair(t, v);
}

template <typename T>
bool operator==(fruit_and vegetables lhs, pair<T, fruit_and_vegetables> rhs) {
    return lhs == rhs.second || lhs == rhs.first;
}
if (something == (apple || pear || orange)) eat_the_yummy_fruit(something);
else feed_to_rabbit(something)
#include <set>
using std::set;

enum fruit_and_vegetables
{
    apples,
    pears,
    tomatoes,
    cucumbers
};

set< fruit_and_vegetables > operator||( fruit_and_vegetables left, fruit_and_vegetables right ) {
    set< fruit_and_vegetables > set;
    set.insert( left );
    set.insert( right );
    return set;
}

set< fruit_and_vegetables > operator||( set<fruit_and_vegetables> left, fruit_and_vegetables right ) {
    left.insert( right );
    return left;
}

set< fruit_and_vegetables > operator||( fruit_and_vegetables left, set<fruit_and_vegetables> right ) {
    right.insert( left );
    return right;
}

bool operator!=( fruit_and_vegetables lhs, set<fruit_and_vegetables> rhs ) {
    return ( rhs.find( lhs ) == rhs.end() );
}

bool operator==( fruit_and_vegetables lhs, set<fruit_and_vegetables> rhs ) {
    return !( lhs != rhs );
}

int main() {

fruit_and_vegetables fav = apples;
if ( fav == ( apples || (pears || tomatoes) ) ) cout << "match apples\n";
fav = cucumbers;
if ( fav == ( (apples || pears) || tomatoes ) ) cout << "Error! matched ghost cucumbers\n";
if ( fav != apples ) cout << "correct no match apples\n";
if ( fav == cucumbers ) cout << "default operator==(FaV, FaV) match\n";
if ( fav == ( pears || apples ) ) cout << "yummi\n";

return 0;
}