std::identity C++20에서 도입된 함수 개체로, 인수를 operator() 변경하지 않고 반환합니다.
메모
<utility> Microsoft 특정 identity 구조체는 사용되지 않으며 이후 버전의 Visual Studio 사용할 수 없습니다. C++20 이상에서는 아래에 설명된 표준 준수 항목인 대신 <functional> 사용합니다std::identity.
std::identity (C++20)
많은 표준 라이브러리 API는 프로젝션 또는 변환 함수와 같은 호출 가능한 인수를 사용합니다. 호출 가능 항목을 전달해야 하지만 데이터를 변경하지 않으려면 전달 std::identity합니다. 이는 범위 알고리즘에서 일반적입니다. 많은 <algorithm> 범위 오버로드에는 기본값인 프로젝션 매개 변수가 있습니다 std::identity{}.
구문
struct identity
{
template <class T>
_NODISCARD constexpr T&& operator()(T&& t) const noexcept;
using is_transparent = int;
};
설명
is_transparent 멤버 형식은 투명한 함수 개체로 표시하는 std::identity 태그입니다. 알고리즘이 먼저 형식을 공통 형식으로 변환하지 않고도 비교 또는 프로젝션을 수행할 수 있음을 나타냅니다. 이 기능은 다른 유형의 조회를 지원하는 결합 컨테이너 및 알고리즘에 유용하므로 임시 개체를 생성하지 않고도 다른 형식을 직접 비교할 수 있습니다.
예제
#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
}
이 예제에서는 키를 사용하여 std::vector<std::string> 검색합니다 std::string_view . 멤버가 is_transparent 있으므로 std::identity 알고리즘은 이러한 형식을 직접 비교하는 것을 알고 있습니다. 이렇게 하면 키를 임시 std::string 로 변환하지 않고 비교를 수행합니다.
#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';
}
}