C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++のstd::setでユーザー定義型を扱う方法

C++のSTLには、std::setという連想コンテナが用意されています。setは要素を常にソートされた順序で自動的に保持し、重複する値の登録を許さない特殊なデータ構造です。通常はintやstringなどの組み込み型を扱いますが、実は自分で定義したクラス(ユーザー定義型)も格納できます。本記事では、その具体的な方法を解説します。

ユーザー定義型をsetに格納するには、そのクラスに対してoperator<(小なり演算子)をオーバーロードし、2つのオブジェクトを比較できるようにする必要があります。この比較演算子が定義されていない場合、setはオブジェクト同士の大小関係を判定できず、ソート済みの順序を維持できません。そのため、コンパイルエラーや例外が発生してしまいます。

サンプルコード

#include <iostream>
#include <set>
using namespace std;

class Student {
    int id, marks;
public:
    Student(int id, int marks) {
        this->id = id;
        this->marks = marks;
    }
    // idを基準にソートするための比較演算子
    bool operator<(const Student& st) const {
        return (this->id < st.id);
    }
    void display() const {
        cout << "(" << id << ", " << marks << ")\n";
    }
};

main() {
    Student s1(5, 70), s2(3, 86), s3(2, 91), s4(2, 60), s5(1, 78), s6(6, 53), s7(4, 59);
    // 同じidを持つ要素は重複として扱われない
    set<Student> st_set;
    st_set.insert(s1);
    st_set.insert(s2);
    st_set.insert(s3);
    st_set.insert(s4);
    st_set.insert(s5);
    st_set.insert(s6);
    st_set.insert(s7);

    set<Student>::iterator it;
    for (it = st_set.begin(); it != st_set.end(); it++) {
        it->display();
    }
}

実行結果

(1, 78)
(2, 91)
(3, 86)
(4, 59)
(5, 70)
(6, 53)

コードのポイント

この例では、学生を表すStudentクラスを定義し、idメンバ変数を基準に比較を行うoperator<を実装しています。これにより、setは各オブジェクトをidの昇順で正しく並べ替えられます。

注目すべきは、s3(id=2, 点数=91)とs4(id=2, 点数=60)のようにidが重複するオブジェクトが存在しても、出力には(2, 91)しか現れない点です。setは比較演算子の結果に基づいて等価性を判断するため、同じidを持つ2つ目以降の要素は挿入されず、最初に登録された要素だけが保持されます。点数(marks)は比較に使われていないため、重複判定には影響しません。

なお、複数の条件でソートしたい場合は、operator<内でidや点数などを組み合わせた比較ロジックを実装するか、setの第2テンプレート引数に独自の比較関数(ファンクタ)を渡す方法もあります。

  1. C++のブール型の型指定子とは?bool型の基本と使い方を解説

    C++におけるブール型の型指定子C++で真偽値(ブール値)を扱うための型指定子は bool です。この型は、true(真) または false(偽) の2つの値のみを持つことができます。基本的な宣言方法bool型の変数は、次のように宣言して初期化できます。bool myBoolean = true;また、falseを代入することも可能です。bool isActive = false;bool型の特徴取り得る値:true または false のみ(trueは1、falseは0としても扱われます)サイズ:通常は1バイト(処理系によって異なる場合があります)ヘッダーファイル:C++言語に組み込まれて

  2. C#で動的データ型(dynamic型)を定義する方法を解説

    C#のdynamic型とはC#では、dynamic型の変数に任意の型の値を格納することができます。この型の変数に対する型チェックは、コンパイル時ではなく実行時(ランタイム)に行われるのが大きな特徴です。dynamic型はC# 4.0で導入された機能で、これを使うことでコンパイル時の型チェックを回避できます。実行時に実際の型が判定されるため、柔軟なコーディングが可能になります。dynamic型の宣言方法dynamic型を宣言するための基本的な構文は以下のとおりです。dynamic <変数名> = 値;たとえば、次のように記述します。dynamic a = 25;object型との違い