如何在if语句的括号中声明变量?

时间:2013-07-11 02:31:46

标签: c++ c++11

我想在if语句的括号中声明一个局部变量。 例如。

if((char c = getc(stdin)) == 0x01)//This is not OK with g++.
{
    ungetc(c, stdin);
}

我想要的是,看看角色是否是我想要的角色。 要说它通常,我想在 if if 的主体中使用变量(char c),但不在 if 之外/ em>的

但是g ++(GCC 4.8.1)在之前说期望的主表达式。 我想知道是否有办法做到这一点,因为我不想要像

这样的东西
char c = getc(stdin);
if(c == 0x01)
{
    bla...
}

3 个答案:

答案 0 :(得分:17)

如果是令人担心的命名空间污染,您可以随时在块中定义if语句:

{
    char c = getc(stdin);
    if(c == 0x01)
    {
        // ...
    }
}

这样c只会持续到达块的末尾。

答案 1 :(得分:10)

我不知道如何创建变量并使用if测试其值,直到看到一些已发布的解决方案。但是,您可以使用switch。这将允许您对其他值(可能EOF)做出反应:

switch (int c = getc(stdin)) {
case 0x01: ungetc(c, stdin); break;
case EOF:  // ...handle EOF
default:   break;
}

您可以始终将if语句放在内联函数中,代码看起来会更清晰一些。如果您确实希望源代码在该位置,但没有在if周围创建一个带有新变量的新范围,那么您可能会接受lambda。

[](int c){ if (c == 0x01) ungetc(c, stdin); }(getc(stdin));

由于您只是与一个值进行比较,因此您的特定问题根本不需要变量,因此您可以这样做:

if (getc(stdin) == 0x01) {
    char c = 0x01;
    ungetc(c, stdin); //or bla...
}

如果您想要与一组值进行比较,那么switch建议是更好的选择。

Jerry Coffin的解决方案看起来很吸引人,但它真的归结为:

if (int c = (getc(stdin) == 0x01)) //...

这可能不是您真正想要的,因为如果您想要与不同于0x01的值进行比较,则不能很好地概括。

Potatoswatter的解决方案似乎更接近你想要的东西,但也许把这种类型推出到一个独立的类中会更好:

template <typename T>
class SetAndTest {
    const T test_;
    T set_;
public:
    SetAndTest (T s = T(), T t = T()) : set_(s), test_(t) {}
    operator bool () { return set_ == test_; }
    operator bool () const { return set_ == test_; }
    operator T & () { return set_; }
    operator T () const { return set_; }
};

//...
if (auto c = SetAndTest<int>(getc(stdin), 0x01)) {
    ungetc(c, stdin); //or bla...
}

答案 2 :(得分:8)

可以if语句中定义变量就好了。例如,这应该编译:

if (int ch = getchar())
    ;

问题是类型(例如int)必须在左括号后立即 。您拥有的额外括号是导致编译失败的原因。所以,如果你真的想要这样做,你需要有点聪明并使用这样的东西:

if (char ch = 0 || ((ch = getchar()) == 0x1))

这使得你可以在表达式的一部分完成之后完成ch完成,然后的创建和初始化,放在ch=getchar()周围的括号中以覆盖分配与比较的优先顺序。

请注意,&&||会进行短路评估,因此您需要小心初始化。您可以使用:

if (char ch = 0 || ...

...或:

if (char ch = 1 && ...

...但是如果您尝试使用if (ch = 1 || ...if (ch = 0 && ...,则短路评估将保持正确的操作数(您真正关心的部分)不被评估。

现在需要注意的是:虽然我有理由相信这段代码符合标准的要求,并且大多数(所有?)当前的编译器都会接受它,这可能会导致大多数程序员阅读代码时出现严重的问题,弄清楚你是什么已经完成了,为什么。在实际代码中使用这种“技术”我会非常犹豫(充其量)。

编辑:有人指出,由此产生的结果可能比最初预期的更具误导性,因此我将尝试澄清情况。会发生什么是从输入读取值。该值已分配给ch并与0x1进行比较。到现在为止还挺好。之后,比较结果(转换为整数,01)将分配给ch。我相信它有足够的序列点,结果是定义的行为。但它可能不是你或任何人想要的东西 - 因此建议你可能不想使用它,并提到它可能会让大多数程序员摸不着头脑,想知道你想要做什么。在与0x1进行比较的非常具体的情况下,ch语句中的if值将为1,但这或多或少是巧合。如果您要与0x2进行比较,则chif的值仍为1,而不是2