使用C++模板或宏进行编译时函数生成

per*_*eal 1 c++ macros templates cuda inline

我有一个在嵌入式系统上运行的代码,它必须运行得非常快.我知道C和宏,这个特定的项目主要用C编码,但它也使用C++模板[越来越多].有一个内联函数:

inline my_t read_memory(uint32 addr) {
  #if (CURRENT_STATE & OPTIMIZE_BITMAP)
    return readOptimized(addr);
  #else
    return MEMORY[addr];
  #endif
}
Run Code Online (Sandbox Code Playgroud)

该函数以优化的方式或基于当前状态的传统方式从存储器读取,并且位图告知是否在特定状态下使用优化.

#define STATE_A 0x0001
#define STATE_B 0x0010
#define STATE_C 0x0100
#define STATE_D 0x1000

#define OPTIMIZE_BITMAP 0x1010 // optimize states d and b
Run Code Online (Sandbox Code Playgroud)

在执行过程中(好的,编译),我尝试重新定义CURRENT_STATE,如下所示:

int main(){
  #define CURRENT_STATE STATE_A
  do_a();
  #undef CURRENT_STATE
  #define CURRENT_STATE STATE_B
  do_b();
  ....
}
Run Code Online (Sandbox Code Playgroud)

所有do_X()函数都会调用read_memory().我无法使这种方法奏效.当我使用#warning语句时,我可以看到当前状态的值总是STATE_A.这不是我的问题,虽然如果你可以帮助我,我会很高兴.所以,我的问题是,有没有办法使用模板而不是宏来做这种事情?

更多信息:我必须使用内联函数,因为我无法导出MEMORY [],这是一个库函数.我真的不想修改函数原型(比如read_memory()...)但它会这样做.另外,原谅我的默默无闻.

非常感谢,

Ant*_*ams 10

内联函数将在声明它的转换单元中解析一次,并且将使用该点处的宏的状态.使用不同定义的宏多次调用该函数不会更改函数的定义.

您可以使用模板执行此操作---如果您将"当前状态"作为模板参数传递,则可以在每个调用点使用不同的实例化:

template<unsigned state>
inline my_t read_memory(uint32 addr) {
  if(state & OPTIMIZE_BITMAP)
    return readOptimized(addr);
  else
    return MEMORY[addr];
}

int main(){
    read_memory<STATE_A>(some_addr);
    read_memory<STATE_B>(some_addr);
    ....
}
Run Code Online (Sandbox Code Playgroud)

编译器将意识到这state & OPTIMIZE_BITMAP是一个常量并优化if每个模板实例化的一个或其他分支.

  • +1,绝对看起来比专业化:) (2认同)

Rod*_*ddy 5

我想你可能误解了编译器(或者更确切地说,预处理器)对#defines的作用.

您的示例(下面引用)没有用,因为#define和#undef之间没有使用CURRENT_STATE.预处理器没有"执行"您的代码,或者此时内联扩展do_a().#defines和宏扩展只能在你的来源的线路中完全出现.

  #define CURRENT_STATE STATE_A
  do_a();
  #undef CURRENT_STATE
Run Code Online (Sandbox Code Playgroud)

这是一个基于预处理器的解决方案,如果模板让你感到恐惧.我们假设do_a()应该使用优化版本.

inline my_t read_memory(uint32 addr) 
{
  return MEMORY[addr];
}

inline my_t read_memory_optimized(uint32 addr) 
{
  return readOptimized(addr);
}
Run Code Online (Sandbox Code Playgroud)

现在,创造 DO_CONFIG.H

#if defined(DO_A) || (defined(DO_C) || ...)
  #define READ_MEMORY read_memory_optimized
#else
  #define READ_MEMORY read_memory
Run Code Online (Sandbox Code Playgroud)

在DO_A.C,顶部添加此项

#define DO_A
#include DO_CONFIG.H
Run Code Online (Sandbox Code Playgroud)

......而x=READ_MEMORY(addr)不是使用x=read_memory(addr).要从优化切换到非优化,只需更改DO_CONFIG.H