identity Structuur

std::identity (geïntroduceerd in C++20) is een functieobject waarvan operator() het argument ongewijzigd wordt geretourneerd.

Opmerking

Er is een Microsoft-specifieke identity structuur van <utility> die is afgeschaft en niet beschikbaar is in latere versies van Visual Studio. Voor C++20 en hoger gebruikt std::identity u in plaats daarvan <functional> het standaard-conforme equivalent dat hieronder wordt beschreven.

std::identity (C++20)

Veel standaardbibliotheek-API's hebben een aanroepbaar argument, zoals een projectie- of transformatiefunctie. Als u een aanroepbare gegevens moet doorgeven, maar u de gegevens niet wilt wijzigen, geeft u dit door std::identity. Dit is gebruikelijk in bereikenalgoritmen. Veel <algorithm> bereiken overbelasten hebben een projectieparameter die standaard wordt gebruikt std::identity{}.

Syntaxis

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

Opmerkingen

Het is_transparent lidtype is een tag die wordt gemarkeerd std::identity als een transparant functieobject. De aanwezigheid ervan geeft aan dat algoritmen vergelijkingen of projecties kunnen uitvoeren zonder eerst typen te hoeven converteren naar een algemene vorm. Dit is handig voor associatieve containers en algoritmen die heterogene opzoekacties ondersteunen, zodat ze verschillende typen rechtstreeks kunnen vergelijken zonder tijdelijke objecten samen te stellen.

Examples

#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 dit voorbeeld wordt gezocht naar een std::vector<std::string>std::string_view sleutel. Omdat std::identity het lid is is_transparent , weet het algoritme deze typen rechtstreeks te vergelijken. Op deze manier wordt de sleutel niet geconverteerd naar een tijdelijk om std::string de vergelijking uit te voeren.

#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';
    }
}