如何在不声明 C/C++ 中附加函数的情况下删除重复的代码?

How can I de-duplicate code without declaring an additional function in C/C++?

本文关键字:情况下 函数 删除 代码 声明 C++      更新时间:2024-09-24

我正在开发一个国际象棋引擎,并正在研究移动生成。例如,这是我为黑骑士生成动作的函数:

/** Pseudolegal moves don't take check into account. */
std::vector<uint8_t>
generate_pseudolegal_bknight_moves(std::shared_ptr<Position> position,
uint8_t square) {
assert(VALID_SQUARE(square));
assert(position->mailbox[square] == B_KNIGHT);
uint8_t candidates[8] = {
NEXT_RANK(PREV_FILE(PREV_FILE(square))),
NEXT_RANK(NEXT_RANK(PREV_FILE(square))),
PREV_RANK(PREV_FILE(PREV_FILE(square))),
PREV_RANK(PREV_RANK(PREV_FILE(square))),
NEXT_RANK(NEXT_FILE(NEXT_FILE(square))),
NEXT_RANK(NEXT_RANK(NEXT_FILE(square))),
PREV_RANK(NEXT_FILE(NEXT_FILE(square))),
PREV_RANK(PREV_RANK(NEXT_FILE(square))),
};
std::vector<uint8_t> moves;
for (int i = 0; i < 8; i++) {
uint8_t candidate = candidates[i];
uint8_t piece = position->mailbox[candidate];
if (VALID_SQUARE(candidate) && (!IS_BLACK_PIECE(piece))) {
moves.push_back(candidate);
}
}
return moves;
}

生成白骑士招式的功能非常相似,只有两个术语(宏)发生了变化:B_KNIGHT->W_KNIGHTIS_BLACK_PIECE->IS_WHITE_PIECE

我不想基本上为每个部分复制移动生成函数,但到目前为止一直这样做,因为它的运行时开销最小。 我可以在 args 中包含bool is_white或其他东西,并使用三元is_white ? W_KNIGHT : B_KNIGHT切换术语,但条件会在运行时增加以前不存在的开销,而且看起来并不那么优雅。我想知道是否有一些编译时功能可以帮助我有一个函数定义。

我想我也可以使用内联函数来尝试减少重复代码的数量,但我想知道是否有比这更好的替代方案。

如果你不想要开销,你可以使用模板参数并if constexpr

enum class Color { WHITE, BLACK };
template <Color C> std::vector<uint8_t>
generate_pseudolegal_knight_moves(std::shared_ptr<Position> position,
uint8_t square) {
...
if constexpr (C == Color::WHITE) {
assert(position->mailbox[square] == W_KNIGHT);
} else {
assert(position->mailbox[square] == B_KNIGHT);
}
...
}
// Call
auto moves = generate_pseudolegal_knight_moves<Color::WHITE>(...);

该标准保证在编译时将评估条件,并且将丢弃错误的分支。

相关文章: