Partilhar via


identity Estrutura

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

Observação

Existe uma estrutura Microsoft específica identity do <utility> que está obsoleta e não está disponível nas versões posteriores do Visual Studio. Para C++20 e posteriores, use std::identity from <functional> em vez disso, que é o equivalente conforme ao padrão descrito abaixo.

std::identity (C++20)

Muitas APIs de biblioteca padrão aceitam um argumento chamável, como uma função de projeção ou transformação. Se precisares de passar uma chamada mas não quiseres alterar os dados, passa std::identity. Isto é comum em algoritmos de intervalos. Muitas <algorithm> sobrecargas de intervalos têm um parâmetro de projeção que por defeito é std::identity{}.

Sintaxe

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

Observações

O is_transparent tipo de membro é uma etiqueta que marca std::identity como um objeto de função transparente. A sua presença indica que os algoritmos podem realizar comparações ou projeções sem necessidade de converter os tipos para uma forma comum primeiro. Isto é útil para recipientes associativos e algoritmos que suportam pesquisa heterogénea, permitindo-lhes comparar 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 a std::vector<std::string> com uma std::string_view chave. Como std::identity tem o is_transparent membro, o algoritmo sabe comparar estes tipos diretamente. Desta forma, a chave não é convertida para um temporário std::string só 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';
    }
}