Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;宏,该宏将执行一个代码块和该块之后的某个命令_C++_Macros_C Preprocessor - Fatal编程技术网

C++ C++;宏,该宏将执行一个代码块和该块之后的某个命令

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

最干净的方法可能是使用RAII容器重置值:

#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(); }
};