是否存在语法怪异的快速/在线方式,允许您检查枚举是否具有指定值的值?
示例:
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;
}
谢谢!
答案 0 :(得分:5)
不是我知道,但您可以做的是为枚举成员分配值2^i
。例如:
enum fruit_and_vegetables
{
apples = (1<<0),
pears = (1<<1),
tomatoes = (1<<2),
cucumbers = (1<<3)
// ...
}
然后你可以用
查看if (something & (apples | pears | tomatoes))
std::cout << "is tasty" << std::endl;
当然,这仅限于尺寸合理的枚举(我认为最多可以包含32个元素)。
如果您的值超过32(64),则必须比此更有创意。 通过几次检查,你仍然可以相当快:
enum fruit_and_vegetables {
apples = 1, //!
pears,
tomatoes,
cucumbers,
// ...
grapes
}
#define FRUIT_AND_VEGETABLES 120
if ( (1<<something) & ((1<<apples) | (1<<pears) | (1<<tomatoes))
|| (1<<(something-32) & ((1<<(apples-32)) | (1<<(pears-32)) | (1<<(tomatoes-32))))
|| ...) {
std::cout << "my keyboard is broken, but tastes good" << std::endl;
}
但这不是一个很好的解决方案。如果你有大量的枚举,并且可以将它们分成几个类,那么我会选择Noah Roberts' answer。
答案 1 :(得分:4)
if (something < tomatoes)...
答案 2 :(得分:4)
啊,这可以很容易地完成......
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)
但如果执行(apple || (pear || orange))
则无效。这可以很容易地修复,但我想保持代码简单。我相信这是迄今为止唯一能够扩展到大型枚举的答案......
答案 3 :(得分:1)
还有另一种方法,它扩展了@bitmask的答案:
假设您可以检查固定数量的标准。因此,您可以使用额外的LUT,而不是使用位掩码作为fruit_and_vegetables
枚举的值(这将限制您的单词大小),您可以使用其他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
...
};
以便检查特定限定符
if (qualifs_LUT[tomato] & is_tasty)
编辑:另一种有趣的方法。考虑(再次)@bitmask:方法。它依赖于2的幂。但素数怎么样?它们的增长速度要慢得多,所以通过为枚举值指定素数,你可以吝啬更多的值,假设产品不会溢出:
enum fruit_and_vegetables {
apples = 2,
pears = 3,
tomatoes = 5,
cucumbers = 7
}
if ((apples * pears * tomatoes) % tomatoes == 0)
printf("it's tasty!");
这个限制了控件集中的项目数。
答案 4 :(得分:1)
您可以编写帮助程序模板来帮助您实现所需的语法:
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;
}
答案 5 :(得分:1)
处理更大,未分类的产品组:
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;
答案 6 :(得分:1)
为什么不使用set< fruit_and_vegetables >
逻辑或多个fruit_and_vegetables
?
如果您在运算符constexpr
和运算符||
重载之前放置==
,
以及参数和结果类型之前,
然后编译器将在编译时评估您的代码(没有运行时开销)
如果可能的话 ;)
可以很好地扩展到更大的a || b || c || c
枚举范围,您可以根据需要将值放在括号中。
#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;
}