我可以在一行上写一个带有变量声明的if语句吗?

时间:2017-09-01 11:13:49

标签: c++ if-statement

我想知道是否有办法将它放在一条线上?

if (auto r = getGlobalObjectByName(word)) r->doSomething; // This works fine

if (!auto r = getGlobalObjectByName(word)) r->doSomething; // Says "expected an expression"

if (auto r = getGlobalObjectByName(word) == false) r->doSomething; // Also doesn't work.

我也试过用额外的括号围绕它,但这似乎不起作用。我发现在一条线上这很方便。

5 个答案:

答案 0 :(得分:49)

从C ++ 17开始,您可以使用initializer if-statement

if (auto r = getGlobalObjectByName(word); !r) r->doSomething;

语义是:

if (init-statement; condition) statement

与#34;传统"的唯一区别if语句是init-statement,它初始化块作用域中的变量,类似于for循环。

答案 1 :(得分:12)

如果你有C ++ 17,请使用 MyECSrepo: Type: "AWS::ECR::Repository" Properties: RepositoryName: !Ref RepoName RepositoryPolicyText: Version: "2012-10-17" Statement: - Sid: AllowAll Effect: Allow Principal: AWS: - arn:aws:iam::00000000000:group/admin Action: - "ecr:*" 表单。如果没有,您有三种选择:

  • 停止尝试将这一切保持在一条线上。例如:

    if (init statement; condition)
  • 使用auto r = getGlobalObjectByName(word); if (!r) r->doSomething();

    else

(请注意,这要求if (auto r = getGlobalObjectByName(word)) {} else r->doSomething(); 是一个智能指针,其中r函数具有非常奇怪的语义.OTOH,我认为这实际上只是一小段例子代码,而不是您的实际代码。)

我认为我只会使用operator bool()表单,如果真的重要,可以将所有内容保存在一行(例如,保留代码的表格格式)。

答案 2 :(得分:4)

你要做的事情很好。通过在中定义变量,如果,则限制其范围。这有助于减少杂散变量在达到目的后的数量。

使用此技术,如果您想要遵循否定路径,则需要使用 else ,如下所示:

if(auto r = getGlobalObjectByName(word))
{
    r->doSomething();
}
else
{
    // r == nullptr
    // so do something else
}

答案 3 :(得分:4)

还有一种方法可以用lambdas和C ++ 14来做到这一点,但看起来确实很傻。

[](auto r){ if(!r)r->doSomething(); }(getGlobalObjectByName(word));

在C ++ 11中你也可以做这个可怕的混乱(同样的想法,只是没有auto

[](decltype(getGlobalObjectByName(word)) r){ if(!r)r->doSomething(); }(getGlobalObjectByName(word));

这肯定不比Martin Bonner提到的更清晰的C ++ 11版本更好:

{
    auto r = getGlobalObjectByName(word);
    if(!r)r->doSomething();
}

此处您的代码清楚地表明您希望r仅在if语句的持续时间内出现。

答案 4 :(得分:2)

在C ++ 17之前,您可以定义一个包装类,如下所示:

#include <utility>
template<typename T>
class NotT
{
    T t;
public:
    template<typename U>
    NotT(U&& u) : t(std::move(u)) {}
    explicit operator bool() const { return !t; }
    T      & value()       { return t; }
    T const& value() const { return t; }
};
template<typename T> NotT<T> Not(T&& t)
{
    return NotT<T>(std::move(t));
}

#include <memory>
#include <iostream>

int main()
{
    if(auto p=Not(std::make_shared<int>(2134)))
        std::cout << "!p: p=" << p.value().get() << '\n';
    else
        std::cout << "!!p: p=" << p.value().get() << ", *p=" << *p.value() << '\n';

}

Live example