8

I just want to know what is the purpose of std::identity? I could not find anything useful on web. I know how it is implemented :

template <typename T>
struct identity
{
    T operator()(T x) const { return x; }
};

why do we actually need this?

MEMS
  • 617
  • 1
  • 6
  • 11
  • Standard doesn't have `std::identity`, all proposals have been removed. You might consider this as a hint. – SergeyA Jan 20 '17 at 15:37
  • the main use of the identity function is to be able to pass an argument wrapped around a function pointer if this is the argument expected. It is common in functional programming and tends to be used a lot in languages like haskell. see: http://stackoverflow.com/questions/25987085/what-do-people-use-the-identity-function-for – Tasos Papastylianou Jan 20 '17 at 15:40
  • http://stackoverflow.com/questions/15202474/default-function-that-just-returns-the-passed-value read this and you'll get it – szpanczyk Jan 20 '17 at 15:42
  • 1
    then what is this? https://en.cppreference.com/w/cpp/utility/functional/identity – JFFIGK Jan 07 '19 at 11:58

5 Answers5

5

Other people already answered the question - it's useful for things like a default for a function-type template parameter, and for haskell-style functional programming.

But your example implementation is not correct. Your code would perform a value copy, which std::identity does not do - it perfectly forwards. It's also constexpr and is transparent.

So this is an example of how it would be implemented, I believe:

    struct identity
    {
        using is_transparent = void;

        template <typename T>
        constexpr T&& operator()(T&& t) const noexcept
        {
            return std::forward<T>(t);
        }
    };
hadriel
  • 631
  • 5
  • 8
3

Standard (up to C++20) doesn't have std::identity, all proposals mentioning it have been removed. When initially suggested, it was supposed to serve the same purpose as std::forward serves in accepted standard, but it conflicted with non-standard extensions and after several iterations was finally removed.

C++20 has std::identity back: https://en.cppreference.com/w/cpp/utility/functional/identity

SergeyA
  • 61,605
  • 5
  • 78
  • 137
2

The struct you have in your code is the identity function T -> T where T is a template parameter. This function isn't useful on its own, but may be useful in other contexts where you need to pass a function parameter and the identify function is the one you want insert there. It's generally useful as a sort-of "do nothing" function.

As to std::identity, I can find no evidence that this struct exists in the C++ standard library.

Cubic
  • 14,902
  • 5
  • 47
  • 92
  • 2
    It's pretty useful to exclude arguments from template argument deduction. Cppreference has an example at http://en.cppreference.com/w/cpp/language/template_argument_deduction – Cubbi Jan 20 '17 at 18:12
  • @Cubbi Unless I'm mistaken, the article you linked to seems to be talking about the identity type transformation rather than the identity function though. Similar concept, but not quite the same thing at least as far as C++ is concerned. – Cubic Jan 20 '17 at 18:19
  • huh, indeed, now I also wonder what the Microsoft identity is for. – Cubbi Jan 20 '17 at 18:21
  • @Cubbi: indeed pretty handy. Boost clamp uses identity to prevent argument deduction for its other arguments but unfortunately std::clamp doesn't use that trick. – gast128 Feb 22 '17 at 08:19
2

While not relevant at the time of the question being asked, C++20 adds std::identity which seem to come from Ranges proposal. Here is its previous definition from Ranges TS where the main usage of it is explained as:

It is used as the default projection for all Ranges TS algorithms.

Predelnik
  • 5,066
  • 2
  • 24
  • 36
0

I don't have std::identity in my libraries, but it should be a useful tool to copy a vector into another one without the nullptr objects in it via std::copy_if.

Adam Hunyadi
  • 1,890
  • 16
  • 32