使用预处理器重新定义循环
Redefining for loops with the preprocessor
我想做一些邪恶的事情。我想重新定义for循环来修改条件。有办法做到这一点吗?
GCC文档支持重新定义关键字:http://gcc.gnu.org/onlinedocs/cpp/Macros.html
我想做的是为C++做一个"概率"包装器,看看我是否可以用它做一些有趣的事情
#include <iostream>
#include <cstdlib>
#define P 0.85
#define RANDOM_FLOAT ((float)rand()/(float)RAND_MAX)
#define RANDOM_CHANCE (RANDOM_FLOAT < P)
#define if(a) if((a) && RANDOM_CHANCE)
#define while(a) while((a) && RANDOM_CHANCE)
// No more for loops or do-while loops
#define do
#define goto
// Doesn't work :(
//#define for(a) for(a) if(!RANDOM_CHANCE) { break; }
int main() {
srand(time(NULL));
//Should output a random list of Y's and N's
for(int i=0; i < 100; ++i) {
if(i < 100) {
std::cout << "Y";
} else {
std::cout << "N";
}
}
std::cout << std::endl;
// Will loop for a while then terminate
int j = 0;
while(j < 100) {
++j;
std::cout << j << "n";
}
std::cout << std::endl;
return 0;
}
一个可能更合理的用途是计算运行程序中的循环迭代次数,例如通过映射
for(int i=0; i < 10; ++i)
至
for(int i=0; i < 10; ++i, ++global_counter)
有可能完成我想做的事情吗?
编辑:谢谢你的回复,我真的很感激!
我可以用它做的一件事是模拟一个公平的硬币(有效地迫使p为0.5),注意如果你有一个有偏差的硬币,Pr(HT)==Pr(TH)。我没有发现这个窍门,但它很有用。这意味着你可以近似P。的任何概率分布
bool coin() {
bool c1 = false;
bool c2 = false;
if(true) {
c1 = true;
}
if(true) {
c2 = true;
}
//If they have different faces.
bool valid = (c1 && !c2) || (!c1 && c2);
bool result = c1;
if(valid) { return result; }
return coin();
}
您是否尝试将else
添加到for
循环中?这应该会让它发挥作用。
#define for(a) for(a) if(!RANDOM_CHANCE) { break; } else
for (int i = 0; i < 10; ++i)
{
// do something
}
/* should roughly compile to:
for (int i = 0; i < 10; ++i) if(!RANDOM_CHANCE) { break; } else
{
// do something
}
or (differing only in whitespace):
for (int i = 0; i < 10; ++i)
if(!RANDOM_CHANCE)
{
break;
}
else
{
// do something
}
*/
您已经展示了它。这里有一个可编译的例子:
#include <iostream>
unsigned globalCounter = 0;
#define for(x) for(x, ++globalCounter)
int main () {
for (int i=0; i<10; ++i);
for (int i=0; i<10; ++i);
std::cout << globalCounter << 'n';
}
这输出20。然而,像这样的现有代码
for (int i=0; i<x; ++i, foobar+=20)
将中断,因为它现在将两个参数传递给for宏。
您需要的是宏重载或可变宏。后者在C99中得到支持,C++11派生了它,所以如果你想让邪恶发生:
unsigned globalCounter = 0;
#define for(...) for(__VA_ARGS__, ++globalCounter)
#include <iostream>
void main () {
int another = 0;
for (int i=0; i<10; ++i, ++another);
for (int i=0; i<10; ++i, ++another);
std::cout << globalCounter << ' ' << another << 'n';
}
然后
g++ --std=c++0x source.cc
./a.out
20 20
我不支持这一点。宏可能会伤害你的孩子。
它不起作用,因为块不再属于for
语句。转换为
for (int i=0; i < 100; ++i)
{
if (!RANDOM_CHANCE)
{
break;
}
}
// unrelated to the 'for' above.
{
if(i < 100) {
std::cout << "Y";
} else {
std::cout << "N";
}
}
相反,你可以写
#define for(...) for(__VA_ARGS__) if(RANDOM_CHANCE)
所以代码变成
for (int i=0; i < 100; ++i)
if (RANDOM_CHANCE)
{
if(i < 100) {
std::cout << "Y";
} else {
std::cout << "N";
}
}
(注意,我使用了可变宏。)
对于global_counter,如果你能保证增量部分永远不会是空的,那么很容易:
#define for(...) for(__VA_ARGS__, ++ global_counter)
否则(例如,代码中有for(;;)
),我认为这是不可能的。
相关文章:
- 在定义字符数组(井字游戏)的 for 循环中应用输入限制
- 在C++中循环访问自定义结构列表的小问题
- 具有迭代器和自定义步长的循环结束条件
- 在 for 循环中定义的临时数组,并分配给属于指针数组的指针
- 循环访问自定义双链表
- 需要帮助定义循环控制变量(while loops)C++
- C++11:没有复制构造函数的自定义基于范围的循环
- c++在循环中定义一组概率分布
- 如何在已定义的名称模式上循环
- C++未定义的行为unordered_map为基于范围的 for 循环中的右值
- 循环依赖结构,使用前向声明时结构的错误重定义
- For 和 while 循环在全局定义的函数中不起作用
- 如何在C++中循环浏览自定义列表
- 基于范围的 for 循环,用于包含C++中的指针的自定义链表,仅返回对象
- 自定义对象构造函数在循环外部循环
- 带有自定义对象的C 范围循环
- 为什么 for 循环不能定义两个作用域的变量?
- 在主循环外部多个文件上定义全局变量
- 在运行时定义循环
- 使用预处理器重新定义循环