これを1行に入れる方法があるのだろうか?
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.
また、余分な角かっこで囲みましたが、うまくいかないようです。これは、1行で行うと非常に便利です。
C++ 17以降では、 initializer if-statement を使用できます。
if (auto r = getGlobalObjectByName(Word); !r) r->doSomething;
セマンティクスは次のとおりです。
if (init-statement; condition) statement
「従来の」ifステートメントとの唯一の違いはinit-statement
:forループと同様に、ブロックスコープ内の変数を初期化します。
C++ 17を使用している場合は、if (init statement; condition)
形式を使用します。そうでない場合は、次の3つの選択肢があります。
これをすべて1行に収めようとするのをやめてください。例えば:
_auto r = getGlobalObjectByName(Word);
if (!r) r->doSomething();
_
else
を使用します。
_if (auto r = getGlobalObjectByName(Word)) {} else r->doSomething();
_
(これはr
がoperator bool()
関数のvery奇妙なセマンティクスを持つスマートポインターであることを必要とすることに注意してください。実際のコードではなくコード)。
本当にがすべてを1行に保持することが重要な場合(たとえば、コードの表形式を保持するため)にのみ、else
フォームを使用すると思います。
あなたがやろうとしていることは問題ありません。 if内で変数を定義することにより、そのscopeを制限します。これは、目的を果たした後の浮遊変数の数を減らすのに役立ちます。
この手法を使用して、negativeパスに従う場合は、次のようにelseを使用する必要があります。
if(auto r = getGlobalObjectByName(Word))
{
r->doSomething();
}
else
{
// r == nullptr
// so do something else
}
ラムダと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ステートメントの期間だけ存在することを明確にしています。
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';
}