【C++】noexcept の使い方 | 例外を送出しないことを明示する

目次

はじめに

C++の関数は、潜在的に例外を投げる可能性があります。しかし、ゲッター関数やムーブコンストラクタのように、「この関数は絶対に例外を送出しない」と分かっているものも多くあります。

C++11で導入された**noexcept指定子は、関数宣言の後ろに付けることで、その関数が例外を投げない**ことをコンパイラに伝えます。これにより、コンパイラはより積極的な最適化を行えるようになり、パフォーマンスが向上する可能性があります。

また、noexceptはプログラマにとっても、関数の仕様を明確にするための重要なドキュメントとしての役割を果たします。


【前提】C++11とは?

C++11は、2011年に正式化されたC++言語のメジャーアップデート版です。noexcept はこのC++11で導入されたため、利用するにはC++11以降に対応したコンパイラが必要です。


noexcept の使い方

1. noexcept: 無条件に例外を送出しない

noexcept(またはnoexcept(true))を付けると、その関数は例外を送出しないとマークされます。もし、noexceptが指定された関数から例外が送出されてしまうと、プログラムは即座にstd::terminateを呼び出して異常終了します。

サンプルコード

#include <iostream>
#include <string>
#include <utility> // move

using namespace std;

class Widget {
private:
    string name_;

public:
    // このゲッター関数は、例外を投げる処理を含まない
    const string& getName() const noexcept {
        return name_;
    }

    // ムーブコンストラクタやムーブ代入演算子は、
    // noexceptにしておくと、STLコンテナなどがより効率的に扱ってくれる
    Widget(Widget&& other) noexcept {
        name_ = move(other.name_);
    }
};

経験則: デストラクタ、ムーブコンストラクタ/ムーブ代入演算子、swap関数など、例外を投げるべきではないと一般的に考えられている関数には、積極的にnoexceptを付けるべきです。


2. noexcept(条件式): 条件付きで例外を送出しない

noexceptのカッコの中に、コンパイル時に評価される条件式を入れることで、条件に応じてnoexcept指定を有効にするか決めることができます。

これは、特にテンプレートプログラミングで、テンプレート引数の型が持つ関数のnoexcept性を引き継ぎたい場合に非常に強力です。

サンプルコード

class Resource {
public:
    void process() const { /* 例外を投げる可能性あり */ }
};
class SafeResource {
public:
    void process() const noexcept { /* 例外を投げない */ }
};

// テンプレート関数
template <typename T>
void execute_process(const T& item) noexcept(noexcept(item.process())) {
    item.process();
}

int main() {
    // is_nothrow_invocable_v はC++17の機能
    cout << boolalpha;
    cout << "execute_process<Resource> はnoexcept? -> " 
         << noexcept(execute_process(Resource{})) << endl; // -> false

    cout << "execute_process<SafeResource> はnoexcept? -> " 
         << noexcept(execute_process(SafeResource{})) << endl; // -> true

    return 0;
}

解説:

  • noexcept(item.process()): noexcept演算子は、引数に渡された式のnoexcept性をbool値で返します。
    • itemResource型の場合: item.process()noexceptではないので、falseを返します。
    • itemSafeResource型の場合: item.process()noexceptなので、trueを返します。
  • void execute_process(...) noexcept(...): execute_process関数自身のnoexcept性が、内部で呼び出すitem.process()noexcept性と連動するようになります。

まとめ

今回は、C++11のnoexcept指定子について解説しました。

  • noexcept: 関数が例外を送出しないことを明示する。コンパイラの最適化を助け、パフォーマンス向上に繋がる可能性がある。
  • デストラクタムーブ操作には、原則としてnoexceptを付けるべき。
  • noexcept(条件): 条件付きでnoexceptを適用し、テンプレートなどで**noexcept性を伝播**させる。

noexceptを適切に使うことで、コンパイラと、コードを読む他のプログラマの両方に対して、関数の挙動に関する重要な情報を提供し、より安全で効率的なコードを書くことができます。

副業から独立まで「稼げる」Webスキルを習得する(PR)

ここまで読んでいただきありがとうございます。 最後に宣伝をさせてください。

「副業を始めたいが、何から手をつければいいかわからない」「独学でスキルはついたが、収益化できていない」という悩みを持つ方には、マンツーマン指導のWebスクール**「メイカラ」**が適しています。

このスクールは、単に技術を教えるだけでなく、**「副業として具体的にどう稼ぐか」**という実務直結のノウハウ提供に特化している点が特徴です。

講師陣は、実際に「副業Webライターから1年で独立して月収100万円」を達成したプロや、現役で利益を出し続けているブロガーなど、確かな実績を持つプレイヤーのみで構成されています。そのため、机上の空論ではない、現場で通用する戦術を学ぶことができます。

副業に特化した強み

  • 最短ルートの提示: 未経験からでも実績を出せるよう、マンツーマンで指導。
  • AI活用の習得: 副業の時間対効果を最大化するための、正しいAI活用スキルも網羅。
  • 案件獲得のチャンス: 運営がWebマーケティング会社であるため、実力次第で社内案件の紹介など、仕事に直結する可能性があります。

受講者の多くは、「在宅でできる仕事を探している」「副業を頑張りたい」という20代・30代・40代が中心です。

受講前には、講師による無料説明が行われます。無理な勧誘はなく、自分に合った副業スタイルやプランを相談できるため、まずは話を聞いてみることから始めてみてはいかがでしょうか。

ブログで稼ぎたいなら「メイカラ」

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次