I have seen this meta function used, but never really understod why and in what context it is required. Can someone explain it with an example?
template <
Prevents template argument deduction:
template
void non_deducible(typename identity::type t) {}
non_deducible(1); // error
non_deducible(1); // ok
template
void first_deducible(T a, typename identity::type b) {}
first_deducible(5, 'A'); // ok
Disables unsafe/unwanted implicit deduction guides (c++17):
template
struct smart_ptr {
smart_ptr(typename identity::type* ptr) {}
};
smart_ptr{new int[10]}; // error
smart_ptr{new int}; // ok
Makes defining type-traits (and other metafunctions) easier:
template
struct remove_pointer : identity {};
template
struct remove_pointer : identity {};
Can be used for tag dispatching:
void foo(identity>) {}
void foo(identity>) {}
template
void bar(T t) {
foo(identity{});
}
Can be used for returning types:
template
constexpr auto foo() {
if constexpr (I == 0)
return identity{};
else
return identity{};
}
decltype(foo<1>())::type i = 3.14f;
Helps to specialize functions accepting a forwarding-reference:
template
void foo(T&& t, identity>) {}
template
void foo(T&& t) { foo(std::forward(t), identity>{}); }
foo(std::vector{});
Provides alternative syntax for declaring types, e.g. pointers/references:
int foo(char);
identity::type* fooPtr = &foo; // int(*fooPtr)(char)
identity::type& strRef = "foo"; // const char(&strRef)[4]
Can be used as a wrapper for code expecting nested T::type
to exist or deferring its evaluation:
struct A {};
struct B { using type = int; };
std::conditional, A, identity>::type::type; // float
std::conditional, B, identity>::type::type; // B
In the past, it used to serve as a workaround for a missing scope operator from the decltype()
specifier:
std::vector v;
identity::type::value_type i;
// nowadays one can say just decltype(v)::value_type
The identity
utility is proposed to be added to c++20:
namespace std {
template
struct type_identity { using type = T; };
template
using type_identity_t = typename type_identity::type;
}