我有一个枚举列表,定义如下:
enum PinEnum {
kPinInvalid,
kPinA0,
kPinA1,
kPinB0,
kPinB1,
kPinC0,
kPinC1,
}
这些枚举中的每一个都需要与另外两个值相关联,即端口和引脚号。目前,我正在通过运行时函数访问它们:
GPIO_TypeDef * PinGetPort(const PinEnum pin) {
switch (pin) {
case kPinA0:
case kPinA1:
return GPIOA;
case kPinB0:
case kPinB1:
return GPIOB;
case kPinC0:
case kPinC1:
return GPIOC;
default:
return NULL;
}
}
uint16_t PinGetPin(const PinEnum pin) {
switch (pin) {
case kPinA0:
case kPinB0:
case kPinC0:
return GPIO_Pin_0;
case kPinA1:
case kPinB1:
case kPinC1:
return GPIO_Pin_1;
default:
return 0;
}
}
特别是,我这样做是因为我不希望大型查找表在运行时占用 RAM(代码大小不是问题)。
有没有办法使用编译时查找表、constexpr 函数或模板构造来执行此操作,以便语句 PinGetPin(kPinA0)和 PinGetPort(kPinA0) 都优化为单个值,而不必经过冗长的函数调用和 case 语句?这些函数的参数将始终是 const PinEnum 类型,其值在编译时已知。
例如,典型的使用场景如下:
const PinEnum kPinStatus = kPinB0;
int main(int argc, char ** argv) {
...
PinGetPort(kPinStatus)->BSRRH = PinGetPin(kPinStatus);
// GPIOB->BSRRH = GPIO_Pin_0; <-- should optimize to this during compilation
...
}
C++11 答案很好。
虽然对于编译时查找表还有其他答案,但我没有看到直接适用于这种情况的答案。它们要么需要字符串递归,要么实际计算并存储一个查找表(如果没有其他方法,这可能最终会出现)。
最佳答案
使用以枚举为参数的模板结构,template specialization , 和 std::integral_constant .
#include <type_traits>
enum class pin { pin0, pin1 };
template<pin> struct lookup_port;
template<pin> struct lookup_num;
template<> struct lookup_port<pin::pin0>
: std::integral_constant<int, 0> { };
template<> struct lookup_num<pin::pin0>
: std::integral_constant<int, 520> { };
template<> struct lookup_port<pin::pin1>
: std::integral_constant<int, 22> { };
template<> struct lookup_num<pin::pin1>
: std::integral_constant<int, 5440> { };
int main()
{
static_assert(lookup_port<pin::pin0>::value == 0, "");
static_assert(lookup_port<pin::pin1>::value == 22, "");
static_assert(lookup_num<pin::pin0>::value == 520, "");
static_assert(lookup_num<pin::pin1>::value == 5440, "");
}
在 C++14 中,您的 switch 函数可以是 constexpr,感谢 relaxed constexpr restrictions .
关于c++ - 枚举的编译时查找表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33374241/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s
我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个应用需要发送用户事件邀请。当用户邀请friend(用户)参加事件时,如果尚不存在将用户连接到该事件的新记录,则会创建该记录。我的模型由用户、事件和events_user组成。classEventdefinvite(user_id,*args)user_id.eachdo|u|e=EventsUser.find_or_create_by_event_id_and_user_id(self.id,u)e.save!endendend用法Event.first.invite([1,2,3])我不认为以上是完成我的任务的最有效方法。我设想了一种方法,例如Model.find_or_cr
我想找到给定字符串中的所有匹配项,包括重叠匹配项。我怎样才能实现它?#Example"a-b-c-d".???(/\w-\w/)#=>["a-b","b-c","c-d"]expected#Solutionwithoutoverlappedresults"a-b-c-d".scan(/\w-\w/)#=>["a-b","c-d"],but"b-c"ismissing 最佳答案 在积极的前瞻中使用捕获:"a-b-c-d".scan(/(?=(\w-\w))/).flatten#=>["a-b","b-c","c-d"]参见Rubyde
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“