C++ C++;宏,该宏将执行一个代码块和该块之后的某个命令
最干净的方法可能是使用RAII容器重置值:C++ C++;宏,该宏将执行一个代码块和该块之后的某个命令,c++,macros,c-preprocessor,C++,Macros,C Preprocessor,最干净的方法可能是使用RAII容器重置值: #include <string> #include <iostream> #include <boost/foreach.hpp> int main() { std::string hello( "Hello, world!" ); BOOST_FOREACH( char ch, hello ) { std::cout << ch; } re
#include <string>
#include <iostream>
#include <boost/foreach.hpp>
int main()
{
std::string hello( "Hello, world!" );
BOOST_FOREACH( char ch, hello )
{
std::cout << ch;
}
return 0;
}
可以将其转换为宏:
for (bool b = false; b == false; b = true, (xyz = 123))
{
// ...
}
用作:
// Assumes T's assignment does not throw
template <typename T> struct ResetValue
{
ResetValue(T& o, T v) : object_(o), value_(v) { }
~ResetValue() { object_ = value_; }
T& object_;
T value_;
};
#define DO_AFTER_BLOCK(expr) \
for (bool DO_AFTER_BLOCK_FLAG = false; \
DO_AFTER_BLOCK_FLAG == false; \
DO_AFTER_BLOCK_FLAG = true, (expr))
我真的不认为宏观方法是个好主意;如果在产品源代码中看到这一点,我可能会感到困惑。您不一定需要宏-您可以使用内部范围变量:
DO_AFTER_BLOCK(xyz = 123)
{
// ...
}
如果使用GCC和-Wshadow
编译,则会收到警告;否则,它将编译为干净的。
你不能写intxyz=xyz内部块中的代码>可靠;一旦对“=”进行了解析,声明就完成了,因此初始值设定项是内部的“xyz”,而不是外部的。不过,两步舞很管用
这种方法的主要缺点是需要修改代码块
如果块中有副作用(如上面的打印语句),则可以调用包含内部块的函数。如果块中没有副作用,为什么要执行它呢
xyz = 123
xyz = 123
xyz = 1
xyz = 123
#包括
静态内部空隙(int xyz)
{
printf(“xyz=%d\n”,xyz);
xyz++;
如果(xyz<1000)
xyz=1;
printf(“xyz=%d\n”,xyz);
}
内部主(空)
{
int xyz=123;
printf(“xyz=%d\n”,xyz);
内(xyz);
printf(“xyz=%d\n”,xyz);
返回(0);
}
除非将循环放入宏中,否则无法使宏在循环后执行命令。说真的?仅仅创建一个作用域变量是一个更好的主意
#include <stdio.h>
static void inner(int xyz)
{
printf("xyz = %d\n", xyz);
xyz++;
if (xyz < 1000)
xyz = 1;
printf("xyz = %d\n", xyz);
}
int main(void)
{
int xyz = 123;
printf("xyz = %d\n", xyz);
inner(xyz);
printf("xyz = %d\n", xyz);
return(0);
}
模板类callfunctionscopeexit{
T;
公众:
callFunctionScopeExit(TTT):T(tt){}
~CallFunctionScopeExit(){t();}
};
在异常等情况下可以保证,而宏版本则肯定不是。我更愿意将此模式用于异常保证,因为它比仅复制int更灵活。为什么要这样做?我有一个具有指针的对象。我需要暂时改变这个指针,因此,将它返回到它的原始值,并且我希望自动化,而不是“忘记”。不需要析构函数,因为此对象已被赋予函数,并且应按给定的方式返回。由于使用的是void main()
,因此得到的结果不好。main
函数始终返回一个int
。其他任何东西都是未定义的行为。有学究风度,然后就有了。当然,如果学究风度就是一切——你知道——一个人可能会犯错误(:太棒了!!非常感谢你!)。感谢所有其他尝试过的人!有点诡计(非模板基类ResetValueBase
,一个用于ResetValueBase const&
的typedef和一个模板辅助函数ResetValue reset(T&,T)
您不需要传入要重置的值的类型。基本上您需要编写ResetValueBase const&reset=reset(xyz,123)
事实上,詹姆斯的宏观解决方案就是答案,至少对我的具体问题是这样的。
#include <stdio.h>
int main(void)
{
int xyz = 123;
printf("xyz = %d\n", xyz);
{
int pqr = xyz;
int xyz = pqr;
printf("xyz = %d\n", xyz);
xyz++;
if (xyz < 1000)
xyz = 1;
printf("xyz = %d\n", xyz);
}
printf("xyz = %d\n", xyz);
return(0);
}
xyz = 123
xyz = 123
xyz = 1
xyz = 123
#include <stdio.h>
static void inner(int xyz)
{
printf("xyz = %d\n", xyz);
xyz++;
if (xyz < 1000)
xyz = 1;
printf("xyz = %d\n", xyz);
}
int main(void)
{
int xyz = 123;
printf("xyz = %d\n", xyz);
inner(xyz);
printf("xyz = %d\n", xyz);
return(0);
}
template<typename T> class CallFunctionOnScopeExit {
T t;
public:
CallFunctionOnScopeExit(T tt) : t(tt) {}
~CallFunctionOnScopeExit() { t(); }
};