Freigeben über


identity Struktur

std::identity (in C++20 eingeführt) ist ein Funktionsobjekt, dessen operator() Argument unverändert zurückgegeben wird.

Hinweis

Es gibt eine Microsoft spezifische identity-Struktur aus <utility>, die veraltet ist und in späteren Versionen von Visual Studio nicht verfügbar ist. Verwenden Sie std::identity<functional> für C++20 und höher stattdessen das standardkonforme Äquivalent, das unten beschrieben wird.

std::identity (C++20)

Viele Standardbibliotheks-APIs verwenden ein aufrufbares Argument, z. B. eine Projektions- oder Transformationsfunktion. Wenn Sie eine aufrufbare, aber keine Daten ändern möchten, übergeben std::identitySie . Dies ist in Bereichsalgorithmen üblich. Viele <algorithm> Bereichsüberladungen verfügen über einen Projektionsparameter, der standardmäßig auf std::identity{}.

Syntax

struct identity
{
    template <class T>
    _NODISCARD constexpr T&& operator()(T&& t) const noexcept;
    using is_transparent = int;
};

Hinweise

Der is_transparent Elementtyp ist ein Tag, das als transparentes Funktionsobjekt markiert std::identity wird. Das Vorhandensein weist darauf hin, dass Algorithmen Vergleiche oder Projektionen durchführen können, ohne zuerst Typen in ein gängiges Formular konvertieren zu müssen. Dies ist nützlich für assoziative Container und Algorithmen, die heterogene Suche unterstützen, sodass sie verschiedene Typen direkt vergleichen können, ohne temporäre Objekte zu erstellen.

Beispiele

#include <algorithm>
#include <functional>
#include <iostream>
#include <ranges>
#include <vector>

int main()
{
    std::vector<int> v{3, 1, 4, 1, 5, 9, 2, 6};

    // Ranges algorithms can apply a projection before comparison.
    // But if you don't want to apply a projection, i.e. you don't want to modify the data
    // before comparison, you can use std::identity to leave each element unchanged.
    // Here, std::identity{} means "project each element as itself".
    // So the comparator sees the original int values unchanged.
    std::ranges::sort(v, std::less{}, std::identity{});

    // This call is equivalent because std::identity{} is the default projection.
    // In both calls, elements are sorted directly; no field extraction or
    // value transformation happens first.
    std::ranges::sort(v);

    for (int n : v)
    {
        std::cout << n << ' ';
    }
    std::cout << '\n';
    // Output: 1 1 2 3 4 5 6 9
}

In diesem Beispiel wird ein std::vector<std::string>std::string_view Schlüssel durchsucht. Da std::identity das is_transparent Element enthalten ist, weiß der Algorithmus, diese Typen direkt zu vergleichen. Auf diese Weise wird der Schlüssel nicht in einen temporären std::string Konvertiert, um den Vergleich zu erledigen.

#include <algorithm>
#include <functional>
#include <iostream>
#include <ranges>
#include <string>
#include <string_view>
#include <vector>

int main()
{
    std::vector<std::string> words{"apple", "banana", "cherry", "date"};
    std::string_view key = "cherry";

    // `std::less<>` is transparent, so it can compare `std::string` and
    // `std::string_view` directly.
    // `std::identity` is also marked transparent (`is_transparent`), so the
    // projection stays type-flexible instead of forcing one fixed type.
    auto it = std::ranges::lower_bound(words, key, std::less<>{}, std::identity{});

    if (it != words.end() && *it == key)
    {
        std::cout << "Found: " << *it << '\n';
    }
}