如何在不制作代码的 2 个版本的情况下切换代码的深层嵌套部分
How to make a deep nested part of code be toggled without making 2 versions of it
我的代码结构如下:
for
for
for
for
{
things
if(condition1||condition2)
}
基本上“if”会检查 2 个依赖于它之前的每个循环的变量,但只有在用户在程序开始时这样说时才需要检查,否则“if”是没有意义的。
我可以使用 if(boolean&&(condition1||condition2))
,它会很好用,除了它会在所有循环的每一次迭代中被检查。
所以我的问题是:如果用户这么说,有没有办法让 C++ 完全禁用“if”(不检查每个循环的条件),而不用和不重复 if???例如:
if(boolean)
{
all the fors
things
if(conditio1||condition2)
}
else
{
all the fors
things
}
这很好用,但如果我以后必须做任何更改,我将不得不写两次,有可能忘记第二次或犯错误。我也有其他 3 部分代码有同样的问题,所以代码会变得很长。
编辑:你们中的一些人认为我们正在谈论微不足道的迭代次数,但在每个完整程序结束时,“如果”必须至少检查 1080 万次。正如我所说,我有(现在有 2 个)更多代码部分存在相同问题,因此可以节省相当多的时间。
太糟糕了 if constexpr
的解决方案使用了 C++17
将您的 for 循环移动到函数中并使用回调作为函数参数。
#include <iostream>
void func(void (*callback)(int i, int j)) {
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
std::cout << "i = " << i << ", j = " << j << ", (i + j) % 3 == " << (i + j) % 3 << "\n";
callback(i, j);
}
}
}
int main() {
bool verbose = false;
std::cin >> verbose;
if (verbose) {
func([](int i, int j){ if((i + j) % 3 == 0) std::cout << "Their sum is divided by three.\n" ; });
}
else {
func([](int i, int j){});
}
}
您可以在这样的函数中编写代码
template<bool Boolean>
void code(/* parameters */)
{
for // ...
for // ...
// all the fors ...
{
// things
if constexpr (Boolean) // compile time branch
{
if(condition1 || condition2)
// ...
}
}
}
if constexpr
只有在Boolean
为真时才会被编译。所以在调用站点你可以做
bool boolean = /* some run-time initialization */
if (boolean)
code<true>(/* arguments */);
else
code<false>(/* arguments */);
请注意,这不是为了性能而应该做的事情,除非您已经测量和分析代码以查看它是否是瓶颈。完成后,您可以使用上述技术。
如果您还没有使用 C++17,整个 if constexpr
块可以替换为
work<Boolean>(/* arguments */);
其中 work
是专门用于仅在 true
情况下工作的函数模板:
template<bool>
void work(/* parameters */) {}
template<>
void work<true>(/* parameters */)
{
if(condition1 || condition2)
// ...
}
我的代码结构如下:
for
for
for
for
{
things
if(condition1||condition2)
}
基本上“if”会检查 2 个依赖于它之前的每个循环的变量,但只有在用户在程序开始时这样说时才需要检查,否则“if”是没有意义的。
我可以使用 if(boolean&&(condition1||condition2))
,它会很好用,除了它会在所有循环的每一次迭代中被检查。
所以我的问题是:如果用户这么说,有没有办法让 C++ 完全禁用“if”(不检查每个循环的条件),而不用和不重复 if???例如:
if(boolean)
{
all the fors
things
if(conditio1||condition2)
}
else
{
all the fors
things
}
这很好用,但如果我以后必须做任何更改,我将不得不写两次,有可能忘记第二次或犯错误。我也有其他 3 部分代码有同样的问题,所以代码会变得很长。
编辑:你们中的一些人认为我们正在谈论微不足道的迭代次数,但在每个完整程序结束时,“如果”必须至少检查 1080 万次。正如我所说,我有(现在有 2 个)更多代码部分存在相同问题,因此可以节省相当多的时间。
太糟糕了 if constexpr
的解决方案使用了 C++17
将您的 for 循环移动到函数中并使用回调作为函数参数。
#include <iostream>
void func(void (*callback)(int i, int j)) {
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
std::cout << "i = " << i << ", j = " << j << ", (i + j) % 3 == " << (i + j) % 3 << "\n";
callback(i, j);
}
}
}
int main() {
bool verbose = false;
std::cin >> verbose;
if (verbose) {
func([](int i, int j){ if((i + j) % 3 == 0) std::cout << "Their sum is divided by three.\n" ; });
}
else {
func([](int i, int j){});
}
}
您可以在这样的函数中编写代码
template<bool Boolean>
void code(/* parameters */)
{
for // ...
for // ...
// all the fors ...
{
// things
if constexpr (Boolean) // compile time branch
{
if(condition1 || condition2)
// ...
}
}
}
if constexpr
只有在Boolean
为真时才会被编译。所以在调用站点你可以做
bool boolean = /* some run-time initialization */
if (boolean)
code<true>(/* arguments */);
else
code<false>(/* arguments */);
请注意,这不是为了性能而应该做的事情,除非您已经测量和分析代码以查看它是否是瓶颈。完成后,您可以使用上述技术。
如果您还没有使用 C++17,整个 if constexpr
块可以替换为
work<Boolean>(/* arguments */);
其中 work
是专门用于仅在 true
情况下工作的函数模板:
template<bool>
void work(/* parameters */) {}
template<>
void work<true>(/* parameters */)
{
if(condition1 || condition2)
// ...
}