C / C ++:开关非整数 [英] C/C++: switch for non-integers

查看:121
本文介绍了C / C ++:开关非整数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常需要选择做什么根据非POD常量元素的值,是这样的:

Often I need to choose what to do according to the value of a non-POD constant element, something like this:

switch( str ) {
  case "foo": ...
  case "bar": ...
  default:    ...
}

不幸的是开关只能与整数使用:错误:开关量不是整数

实施这样的事情,最琐碎的方法是再有就是如果 A 的序列s:

The most trivial way to implement such thing is then to have is a sequence of ifs:

if( str == "foo" )      ...
else if( str == "bar" ) ...
else                    ...

但这种方法看起来脏脏的,应该花费O(n),其中n是病例数,而一块code的成本可能O(log n)的在最坏的情况下,用二进制搜索。

But this solution looks dirty and should cost O(n), where n is the number of cases, while that piece of code could cost O(log n) at the worst case with a binary search.

使用一些数据结构(如地图),它可能是能够获得重新presenting字符串(为O(log n))的一个整数,然后用一个O(1)开关,或者人们可以通过嵌套实现一个静态的二进制排序如果■在正确的方式,但还是这些的破解的要求很多编码,使得一切更加复杂和难以维护。

Using some data structs (like Maps) it could be possible to obtain an integer representing the string ( O(log n) ), and then use an O(1) switch, or one could implement a static binary sort by nesting ifs in the right way, but still these hacks would require a lot of coding, making everything more complex and harder to maintain.

什么是做到这一点的最好方法是什么? (快速,干净,简单,因为开关语句)

What's the best way to do this? (fast, clean and simple, as the switch statement is)

推荐答案

使用一些讨厌的宏观和模板魔术有可能获得在与pretty语法编译时的展开二进制搜索 - 但比赛(案例)必须的整理 fastmatch.h

Using some nasty macro and template magic it's possible to get an unrolled binary search at compiletime with pretty syntax -- but the MATCHES ("case") have to be sorted: fastmatch.h

NEWMATCH
MATCH("asd")
  some c++ code
MATCH("bqr")
  ... the buffer for the match is in _buf
MATCH("zzz")
  ...  user.YOURSTUFF 
/*ELSE 
  optional
*/
ENDMATCH(xy_match)

这将产生(大约)函数布尔xy_match(字符*&放大器; _buf,T&安培;用户),所以它必须是在外部的水平。说它例如搭配:

This will generate (roughly) a function bool xy_match(char *&_buf,T &user), so it must be at the outer level. Call it e.g. with:

xy_match("bqr",youruserdata);

以及是隐式的,你也不能落下流通。它也没有大量记载,对不起。但你会发现,有一些使用量的可能性,看看。注意:只有G ++测试

And the breaks are implicit, you cannot fall-thru. It's also not heavily documented, sorry. But you'll find, that there are some more usage-possibilities, have a look. NOTE: Only tested with g++.

lambda表达式和初始化列表让事情变得prettier(不涉及宏!):

Lambdas and initializer list make things much prettier (no macros involved!):

#include <utility>
#include <algorithm>
#include <initializer_list>

template <typename KeyType,typename FunPtrType,typename Comp>
void Switch(const KeyType &value,std::initializer_list<std::pair<const KeyType,FunPtrType>> sws,Comp comp) {
  typedef std::pair<const KeyType &,FunPtrType> KVT;
  auto cmp=[&comp](const KVT &a,const KVT &b){ return comp(a.first,b.first); };
  auto val=KVT(value,FunPtrType());
  auto r=std::lower_bound(sws.begin(),sws.end(),val,cmp);
  if ( (r!=sws.end())&&(!cmp(val,*r)) ) {
    r->second();
  } // else: not found
}

#include <string.h>
#include <stdio.h>
int main()
{
  Switch<const char *,void (*)()>("ger",{ // sorted:                      
    {"asdf",[]{ printf("0\n"); }},
    {"bde",[]{ printf("1\n"); }},
    {"ger",[]{ printf("2\n"); }}
  },[](const char *a,const char *b){ return strcmp(a,b)<0;});           
  return 0;
}

这是这个想法。更完整的实现可以在这里找到: switch.hpp

That's the idea. A more complete implementation can be found here: switch.hpp.

我在这个问题上采取最新采用先进的C ++ 11元编程
  产生在编译时搜索特里
  不同于previous的方法,这将处理的未分类
  案例分支机构/串就好了;它们只需要成为字符串文字。
  G ++也允许constexpr他们,而不是铛(如HEAD 3.9.0 /树干274233)的。

My newest take on this problem uses advanced c++11 metaprogramming to generate a search-trie at compile time. Unlike the previous approaches, this will handle unsorted case-branches/strings just fine; they only have to be string-literals. G++ also allows constexpr for them, but not clang (as of HEAD 3.9.0 / trunk 274233).

在每个字典树节点switch语句被用来利用编译器的先进code发生器。

In each trie node a switch-statement is utilized to harness the compiler's advanced code generator.

全面实施可在github上: smilingthax / cttrie

The full implementation is available at github: smilingthax/cttrie.

这篇关于C / C ++:开关非整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆