読者です 読者をやめる 読者になる 読者になる

優先順位付き大小比較

C++

優先順位付きでoperator<()を定義するにはどうすればいいでしょうか。
Windowsエクスプローラで言うところの、「ファイル種別順に並べて、同じファイル種別のものはファイル名順に並べる」というようなものです。


これは、std::tupleのoperator<()をそのまま使えばできます。クラスのメンバ変数をタプル化してstd::tupleの比較演算子を使います。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <tuple>

struct File {
    std::string type;
    std::string name;

    File(const std::string& type, const std::string& name)
        : type(type), name(name) {}
};

bool operator<(const File& a, const File& b)
{
    // ファイル種別、ファイル名の順番で優先順位を付けて比較
    return std::tie(a.type, a.name) < std::tie(b.type, b.name);
}

int main()
{
    std::vector<File> files = {
        {"text", "b.txt"},
        {"application", "b.exe"},
        {"application", "a.exe"},
        {"text", "a.txt"}
    };

    // 並べ替え
    std::sort(files.begin(), files.end());

    for (const File& file : files) {
        std::cout << file.type << ", " << file.name << std::endl;
    }
}
application, a.exe
application, b.exe
text, a.txt
text, b.txt

std::tie()関数は、引数として渡された変数への参照から、参照のタプルを作ります。ここではstd::tupleができます。なので、コピーコストがかからず、単に型変換のみが行われます。


こういう処理は、一覧画面のようなものを作る場合によく必要になります。


参照:
std::tie() - cpprefjp
operator<(tuple, tuple) - cpprefjp