Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
std::identity (introduceras i C++20) är ett funktionsobjekt vars operator() returnerar argumentet oförändrat.
Anmärkning
Det finns en Microsoft-specifik identity struktur från <utility> som är inaktuell och inte är tillgänglig i senare versioner av Visual Studio. För C++20 och senare använder du std::identity från <functional> i stället, vilket är den standardkonsekvivalent som beskrivs nedan.
std::identity (C++20)
Många standardbiblioteks-API:er har ett anropsbart argument, till exempel en projektions- eller transformeringsfunktion. Om du behöver skicka en anropsbar men inte vill ändra data skickar du std::identity. Detta är vanligt i intervallalgoritmer. Många <algorithm> intervallöverlagringar har en projektionsparameter som standard är std::identity{}.
Syntax
struct identity
{
template <class T>
_NODISCARD constexpr T&& operator()(T&& t) const noexcept;
using is_transparent = int;
};
Anmärkningar
Medlemstypen is_transparent är en tagg som markerar std::identity som ett transparent funktionsobjekt. Dess närvaro indikerar att algoritmer kan utföra jämförelser eller projektioner utan att behöva konvertera typer till ett gemensamt formulär först. Detta är användbart för associativa containrar och algoritmer som stöder heterogen sökning, så att de kan jämföra olika typer direkt utan att skapa tillfälliga objekt.
Exempel
#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
}
Det här exemplet söker efter en std::vector<std::string> med en std::string_view nyckel. Eftersom std::identity har is_transparent medlemmen vet algoritmen att jämföra dessa typer direkt. På så sätt konverteras inte nyckeln till en tillfällig std::string bara för att göra jämförelsen.
#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';
}
}