C++の「長い矢印」演算子(--->)とは? その正体と仕組みを実装例付きで解説
C++に「長い矢印」演算子は存在しない
結論から言うと、C++に ---> のような「長い矢印」演算子は存在しません。しかし、一見するとそのような演算子が動いているように見えるコードを書くことは可能です。そのカラクリを理解するには、まず「ラッパー型」という存在を知っておく必要があります。
ラッパー型と operator-> の役割
C++では、値を包み込むためのラッパー型を作ることがよくあります。std::unique_ptr、std::shared_ptr、std::optional などがその代表例です。これらの型は通常、中身の値へのアクセサとして .get() というメンバ関数を持ち、それに加えて、生ポインタと同じ感覚で格納値へ直接アクセスできる operator-> も提供しています。
問題:入れ子になったラッパーの扱いづらさ
困ったことに、こうしたラッパー型が何重にも入れ子になることがあります。そうなると、目的の値にたどり着くまでに .get() を何度も呼び出したり、間接参照を繰り返したりしなければなりません。
wrapper<wrapper<std::string>> wp; wp.get().get().length(); wp.get()->length();
1つ目の .get() を矢印 -> で置き換えられるなら、2つ目も同じように置き換えられたら読みやすいのに……と感じるのは自然なことです。
「長い矢印」の登場
そこでC++コミュニティで有名になったのが、次のような「長い矢印」を使った書き方です。
wrapper<wrapper<std::string>> wp; wp--->length();
さらに別の層でラップされている場合はどうするのか? 答えは簡単、矢印をもっと長くすればいいのです。
wrapper<wrapper<wrapper<std::string>>> wp; wp----->length();
その正体:複数の演算子の組み合わせ
もちろん、この「長い矢印」は単一の演算子ではありません。正体は、通常の -> 演算子と後置デクリメント演算子 -- を組み合わせたものです。
つまり wp---->length() と書いた場合、コンパイラはこれを ((wp--)--)->length() として解釈します。
ここで、後置 -- を「間接参照と同じ働きをする」ように定義しておけば、デクリメントの連続があたかも矢印が伸びていくように見え、「長い矢印」さらには「もっと長い矢印」が完成するというわけです。
実装例
template <typename T>
class wrapper {
public:
T* operator->() { return &t; }
T& operator--(int) { return t; }
private:
T t;
};まとめ
「長い矢印」は公式の演算子ではなく、operator-> と後置 -- のオーバーロードを組み合わせて作り出す、いわば言語仕様の隙間を突いたトリックです。実用性はともかく、演算子オーバーロードと構文解析の規則がどのように働くのかを学ぶには絶好の題材と言えるでしょう。
-
C#の「is」演算子とは?目的と使い方を実例付きで解説
C#の「is」演算子とはC#における「is」演算子は、オブジェクトの実行時の型(ランタイム型)が、指定した型と互換性があるかどうかを判定するために使用されます。判定結果はbool値(true / false)として返されるため、条件分岐と組み合わせて使われることが多い演算子です。基本構文is演算子の基本的な構文は以下の通りです。expr is typeexpr:判定対象となる式type:比較対象となる型の名前式 expr の実行時の型が type と互換性がある場合は true を、互換性がない場合は false を返します。使用例以下は、C#でis演算子を使用してオブジェクトの型を判定する例
-
C#の演算子の優先順位とは?基本ルールとサンプルコードで解説
演算子とは演算子(オペレーター)とは、コンパイラに対して特定の数学的処理や論理処理を実行するよう指示するための記号です。C#には、算術演算子・関係演算子・論理演算子など、さまざまな種類の演算子が用意されています。演算子の優先順位とは演算子の優先順位とは、1つの式の中で各項がどのようにグループ化され、どの順番で評価されるかを決めるルールです。この優先順位は式の評価結果に直接影響します。すべての演算子が同じ優先順位を持つわけではなく、たとえば乗算演算子(*)は加算演算子(+)よりも高い優先順位を持ちます。そのため、a + b * c という式は (a + b) * c ではなく a + (b *