Compartilhar via


identity Estrutura

std::identity (introduzido em C++20) é um objeto de função cujo operator() argumento retorna inalterado.

Observação

Há uma estrutura identity específica de Microsoft de <utility> que foi preterida e não está disponível em versões posteriores do Visual Studio. Para C++20 e posterior, use std::identity em <functional> vez disso, que é o equivalente de conformidade padrão descrito abaixo.

std::identity (C++20)

Muitas APIs de biblioteca padrão assumem um argumento que pode ser chamado, como uma função de projeção ou transformação. Se você precisar passar um callable, mas não quiser alterar os dados, passe std::identity. Isso é comum em algoritmos de intervalos. Muitas <algorithm> sobrecargas de intervalos têm um parâmetro de projeção que usa std::identity{}como padrão .

Sintaxe

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

Comentários

O is_transparent tipo de membro é uma marca que marca std::identity como um objeto de função transparente. Sua presença indica que os algoritmos podem executar comparações ou projeções sem precisar converter tipos em um formulário comum primeiro. Isso é útil para contêineres e algoritmos associativos que dão suporte à pesquisa heterogênea, permitindo que eles comparem diferentes tipos diretamente sem construir objetos temporários.

Exemplos

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

Este exemplo pesquisa um std::vector<std::string> com uma std::string_view chave. Como std::identity tem o is_transparent membro, o algoritmo sabe comparar esses tipos diretamente. Dessa forma, a chave não é convertida em um temporário std::string apenas para fazer a comparação.

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