我的宏观有点顽皮
Is my macro a little bit too naughty?
我做了一个宏。我担心这可能有点"太调皮",因为宏是邪恶的。
这是没有宏的代码:
case SDLK_a:
_buffer_.InsertAtCursor('a');
_buffer_.MutableCursor().Right();
break;
这是宏定义及其用法:
#define SDLK_KEY_CASE_MACRO(X, Y)
{
case X:
_buffer_.InsertAtCursor(Y);
_buffer_.MutableCursor().Right();
break;
}
SDLK_KEY_CASE_MACRO(SDLK_b, 'b');
SDLK_KEY_CASE_MACRO(SDLK_c, 'c');
SDLK_KEY_CASE_MACRO(SDLK_d, 'd');
SDLK_KEY_CASE_MACRO(SDLK_e, 'e');
SDLK_KEY_CASE_MACRO(SDLK_f, 'f');
SDLK_KEY_CASE_MACRO(SDLK_g, 'g');
SDLK_KEY_CASE_MACRO(SDLK_h, 'h');
SDLK_KEY_CASE_MACRO(SDLK_i, 'i');
SDLK_KEY_CASE_MACRO(SDLK_j, 'j');
SDLK_KEY_CASE_MACRO(SDLK_k, 'k');
SDLK_KEY_CASE_MACRO(SDLK_l, 'l');
SDLK_KEY_CASE_MACRO(SDLK_m, 'm');
SDLK_KEY_CASE_MACRO(SDLK_n, 'n');
SDLK_KEY_CASE_MACRO(SDLK_o, 'o');
SDLK_KEY_CASE_MACRO(SDLK_p, 'p');
SDLK_KEY_CASE_MACRO(SDLK_q, 'q');
SDLK_KEY_CASE_MACRO(SDLK_r, 'r');
SDLK_KEY_CASE_MACRO(SDLK_s, 's');
SDLK_KEY_CASE_MACRO(SDLK_t, 't');
SDLK_KEY_CASE_MACRO(SDLK_u, 'u');
SDLK_KEY_CASE_MACRO(SDLK_v, 'v');
SDLK_KEY_CASE_MACRO(SDLK_w, 'w');
SDLK_KEY_CASE_MACRO(SDLK_x, 'x');
SDLK_KEY_CASE_MACRO(SDLK_y, 'y');
SDLK_KEY_CASE_MACRO(SDLK_z, 'z');
显然,这为我节省了很多打字和许多代码。该代码还编译并运行正常。
- 但是这宏观顽皮吗?(这可能会产生意外行为,还是我不应该在代码中使用此"作弊"的原因吗?(
像任何理智的系统一样, SDL_SCANCODE_A
(aka SDLK_a
(处于连续的整数范围内,并且一直以SDL_SCANCODE_Z
为顺序。'a'
通过'z'
也是如此。
if( val >= SDLK_a && val <= SDLK_z ) {
_buffer_.InsertAtCursor( 'a' + (val-SDLK_a) );
_buffer_.MutableCursor().Right();
} else {
// handle other cases
}
这比宏壁更高效,更短,更清晰。
您可能必须重复数字。
对于特殊字符(标签,引号等(,我不会依靠事物很好地出现。在那里您需要有一个短表
struct SDL_table {
unsigned code;
char value;
};
SDL_table table[] = {
{SDL_SCANCODE_TAB, 't'},
// ... etc
};
然后,在较早的检查失败之后,快速搜索该表
auto it = std::find_if( std::begin(table), std::end(table), [&](SDL_table t) { return t.code == val; } );
if (it != std::end(table)) {
_buffer_.InsertAtCursor( it->value );
_buffer_.MutableCursor();
} else {
// deal with unrecognized scancode
}
此时我可能会重构_buffer_
代码。
char SDLK_to_char( unsigned sdlk ) {
if( sdlk >= SDLK_a && sdlk <= SDLK_z )
return 'a' + (val-SDLK_a);
if( sdlk >= SDLK_0 && sdlk <= SDLK_9 )
return '0' + (sdlk-SDLK_0);
struct SDLK_entry {
unsigned code;
char value;
};
static const SDLK_entry table[] = {
{SDL_SCANCODE_TAB, 't'},
// ... etc
};
auto it = std::find_if( std::begin(table), std::end(table),
[&](auto&& t) { return t.code == sdlk; }
);
if (it != std::end(table))
return it->value;
return 0; // null for failure
}
然后
char c = SDLK_to_char( sdlk );
if (c) {
_buffer_.InsertAtCursor( c );
_buffer_.MutableCursor().Right();
}
好吧,我会避开宏 - 即使我必须用案例编写完整的 switch
。
,但首先我会考虑一种替代方法。
例如,查找表将SDLK_...
转换为...
。在C 中,您可以基于std::map
喜欢:
std::map<SDLK_type, char> look_up_table = {{SDLK_a, 'a'}, {SDLK_b, 'b'}};
auto i = look_up_table.find(SDLK_value);
if (i != look_up_table.end())
{
char c = i->second;
_buffer_.InsertAtCursor(c);
_buffer_.MutableCursor().Right();
}
else
{
std::cout << "Not found" << std::endl;
}
相关文章:
- 我的神经网络不起作用 [XOR 问题]
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 我的字符计数代码计算错误.为什么
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- cmake在我的项目中所需的所有静态库都不成功
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 为什么我的for循环不能正确获取argv
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 0-1背包代码中的错误.我的代码中有什么错误
- 当我的阵列太大时出现分段错误
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 为什么二进制搜索在我的测试中不起作用
- 如何指定我希望我的LIB链接到的DLL文件?-Visual Studio 2019
- 我的代码中有错误吗?使用BGI图形的C++代码对我不起作用
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- OpenGL在启用深度测试时不会丢弃我的碎片
- 为什么我的 std::ref 无法按预期工作?
- clang整洁10忽略了我的NOLINT命令
- 我的宏观有点顽皮