identity type trait

172 views
Skip to first unread message

Matthew Fioravante

unread,
Feb 19, 2015, 12:28:20 PM2/19/15
to std-pr...@isocpp.org
This would be a proposal for the most simple type trait
 
template <typename T>
struct identity { using type = T; }

template <typename T>
using identity_t = typename identity<T>::type;

One use case for this type trait is to resolve overloading conflicts when you want overloading to only trigger off of one function parameter.
 
template <typename T> void p0(vector<T>& v, T value);
template <typename T> void p1(vector<T>& v, identity_t<T> value);
void foo() {
  std
::vector<string> strings;

  p0
(strings, "abc"); //Error cannot deduce type T (string vs const char[4])
  p1
(strings, "abc"); //Ok, T is string
}

Ville Voutilainen

unread,
Feb 19, 2015, 12:36:06 PM2/19/15
to std-pr...@isocpp.org
It has been rejected and removed before. See

http://cplusplus.github.io/LWG/lwg-defects.html#939

You can use common_type_t<T, T> for the same effect, I think.

Nevin Liber

unread,
Feb 19, 2015, 12:41:46 PM2/19/15
to std-pr...@isocpp.org

On 19 February 2015 at 11:36, Ville Voutilainen <ville.vo...@gmail.com> wrote:
It has been rejected and removed before. See

http://cplusplus.github.io/LWG/lwg-defects.html#939

But since then N3766 was received favorably in LEWG.  I believe the current status is that we are waiting on an updated paper.
--
 Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com(847) 691-1404

Ville Voutilainen

unread,
Feb 19, 2015, 12:44:25 PM2/19/15
to std-pr...@isocpp.org
On 19 February 2015 at 19:41, Nevin Liber <ne...@eviloverlord.com> wrote:
>
> On 19 February 2015 at 11:36, Ville Voutilainen
> <ville.vo...@gmail.com> wrote:
>>
>> It has been rejected and removed before. See
>>
>> http://cplusplus.github.io/LWG/lwg-defects.html#939
>
>
> But since then N3766 was received favorably in LEWG. I believe the current
> status is that we are waiting on an updated paper.


Cool, thanks for the update.

Jeffrey Yasskin

unread,
Feb 19, 2015, 1:34:06 PM2/19/15
to std-pr...@isocpp.org
Yep. Its author is a slacker and would appreciate someone else taking over the update. LEWG's comments are at http://wiki.edg.com/twiki/bin/view/Wg21chicago2013/N3766.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

Zhihao Yuan

unread,
Feb 19, 2015, 2:56:56 PM2/19/15
to std-pr...@isocpp.org
On Thu, Feb 19, 2015 at 12:41 PM, Nevin Liber <ne...@eviloverlord.com> wrote:
>
> But since then N3766 was received favorably in LEWG. I believe the current
> status is that we are waiting on an updated paper.

But no "favorability" between the two options was not given.

I'm in favor of `identity_of` since I see motivation to rename,
but don't see motivation to standardize SGI `identity`.

Of course `identity_of_t` is bad, but I don't mind to just call
it `identity_t`. Breaking naming consistency a little bit is
worthy here from my point of view.

--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://bit.ly/blog4bsd

Vicente J. Botet Escriba

unread,
Feb 19, 2015, 5:35:15 PM2/19/15
to std-pr...@isocpp.org
Le 19/02/15 19:33, 'Jeffrey Yasskin' via ISO C++ Standard - Future Proposals a écrit :
Yep. Its author is a slacker and would appreciate someone else taking over the update. LEWG's comments are at http://wiki.edg.com/twiki/bin/view/Wg21chicago2013/N3766.


I missed this proposal.
IMHO, we have several kind of identity functions:

A * tag type - id<T>


template<class T>
struct id  {};

Can be used to overload on the function result

M1 f(id<M1>, X);
M2 f(id<M2>, X);

B * meta-function - 
  id<T>::type

template<class T>
struct id  {
  uisng type  = T,
};

used to omit from deduction

M f(M, id<T>::type);

and also as type trait definition

template<class T>
struct is_trait : id<TT<T>> {};

C * alias meta-function - id_t<T>

  template <class T>
  using id_t = typename id<T>::type;

A shortcut

D * meta-function class (type constructor) - id::apply<T>

struct id {
  template <class T>
  using apply = id_t<T>;
};

E * function object - id_c<T>{}(x), id<T>(x)

template <class U>
struct id_c {
  template <class T> // requires ???(T,U)
  T&& operator()(T&&) const;
};

template <class T>
constexpr id_c<T> id = {};

F * polymorphic function object - id_c{}(x),
id{}(x)
struct id_c {
  template <class T>
  T&& operator()(T&&)
const;
};

constexpr id_c id = {};

G * polymorphic lambda - id(x)

auto id = [](auto&& x) { return x; }

Just wondering which identity classes/functions we want to standardize. 

F seems more general than G as it is a id constexpr.

With an eval helper

template <class T>
using eval = typename T::type;

use case C id_t<T> is equivalent to eval<id, T>

With a quote helper

template <template <class ...> class TC>
struct quote {
  template <class ... Ts>
  using apply = TC<Ts...>;
};

use case D id::apply is equivalent to quote<id>

Vicente

Arthur O'Dwyer

unread,
Feb 19, 2015, 10:15:30 PM2/19/15
to std-pr...@isocpp.org
On Thursday, February 19, 2015 at 10:34:06 AM UTC-8, Jeffrey Yasskin wrote:
On Thu, Feb 19, 2015 at 9:41 AM, Nevin Liber <ne...@eviloverlord.com> wrote:

But since then N3766 was received favorably in LEWG.  I believe the current status is that we are waiting on an updated paper. 

Yep. Its author is a slacker and would appreciate someone else taking over the update. LEWG's comments are at http://wiki.edg.com/twiki/bin/view/Wg21chicago2013/N3766.

wiki.edg.com requires a login and password in order to view pages, and when I try to create a login via
it sends me to a "403 Forbidden" page at
So I can't see the LEWG comments.

But if I could see them, I'd be happy to update the proposal accordingly.

(My personal view so far is that identity<T>::operator() shouldn't exist; just identity<T>::type and its alias identity_t<T>. But I wonder what LEWG's view was.)

–Arthur

Zhihao Yuan

unread,
Feb 19, 2015, 11:26:07 PM2/19/15
to std-pr...@isocpp.org
On Thu, Feb 19, 2015 at 10:15 PM, Arthur O'Dwyer
<arthur....@gmail.com> wrote:
>
> wiki.edg.com requires a login and password in order to view pages, and when
> I try to create a login via
> http://wiki.edg.com/twiki/bin/view/TWiki/TWikiRegistration
> it sends me to a "403 Forbidden" page at
> http://wiki.edg.com/twiki/bin/register/Main/WebHome
> So I can't see the LEWG comments.
>
> But if I could see them, I'd be happy to update the proposal accordingly.

Write a new one, bring it to Lenexa meeting, and
you will get the access.

>
> (My personal view so far is that identity<T>::operator() shouldn't exist;
> just identity<T>::type and its alias identity_t<T>. But I wonder what LEWG's
> view was.)
>

LEWG spent some time on discussing how to make
the operator() work in Chicago, including constraining
the template and choosing the header file choice, but
no poll was taken to show which approach is favored.
If you want to champion one approach, please provide
the reason in your paper.

Also, if you want to use the name `identity`, you need
a survey on existing implementations to see whether
the old SGI `identity` is still in use, etc.

Vicente J. Botet Escriba

unread,
Feb 22, 2015, 4:42:22 AM2/22/15
to std-pr...@isocpp.org
Le 20/02/15 05:25, Zhihao Yuan a écrit :
On Thu, Feb 19, 2015 at 10:15 PM, Arthur O'Dwyer
<arthur....@gmail.com> wrote:
wiki.edg.com requires a login and password in order to view pages, and when
I try to create a login via
http://wiki.edg.com/twiki/bin/view/TWiki/TWikiRegistration
it sends me to a "403 Forbidden" page at
http://wiki.edg.com/twiki/bin/register/Main/WebHome
So I can't see the LEWG comments.

But if I could see them, I'd be happy to update the proposal accordingly.
Write a new one, bring it to Lenexa meeting, and
you will get the access.

(My personal view so far is that identity<T>::operator() shouldn't exist;
just identity<T>::type and its alias identity_t<T>. But I wonder what LEWG's
view was.)

LEWG spent some time on discussing how to make
the operator() work in Chicago, including constraining
the template and choosing the header file choice, but
no poll was taken to show which approach is favored.
If you want to champion one approach, please provide
the reason in your paper.

Also, if you want to use the name `identity`, you need
a survey on existing implementations to see whether
the old SGI `identity` is still in use, etc.


I propose
* to use id instead of identity to avoid the backward compatibility constraint and
* to remove the operator() from id<T> as it is not really needed, id<>{} is the identity function object.

Would the following
be less controversial

template <class T=void>
struct id {
  using type = T;
};

template <class T>
using id_t = typename id<T>::type;

template <>
struct id<void> {
  using type = void;
  template <class U>
  U&& operator(U&& u) { return forward<U>(u); }
};

The drawback is that to name the identity function we need id<>{}

An alternative is to place the id meta function on a meta namespace (As Eric's meta library [1] does) and define an id lambda function (constexpr function object) as Lousi's Hana library does [1]

namespace meta {


  template <class T>
   struct id {
    using type = T;
   };

   template <class T>
   using id_t = typename id<T>::type;

}

/* constexpr*/ auto id = [](auto&& x) { return forward<decltype(x)>(x); };

Vicente

[1]. See https://github.com/ericniebler/meta/blob/master/include/meta/meta.hpp

Miro Knejp

unread,
Feb 22, 2015, 6:47:55 AM2/22/15
to std-pr...@isocpp.org
Just a heads up: There might be resistance to "id" based on it being a builtin type in Objective-C, as is "id<X>". Those are very frequently used and at least one compiler (Clang) can parse both languages combined as Obejctive-C++ to bridge the two, which then might result in ambiguities. So even though it is not a C++ problem per se it is a possible conflict worth keeping in might.

Matthew Fioravante

unread,
Feb 22, 2015, 10:01:04 AM2/22/15
to std-pr...@isocpp.org
"id" also commonly means identifier. The name could be misleading.

Another possibility could be std::same<T> or maybe std::identical<T>

Scott Prager

unread,
Feb 22, 2015, 1:31:11 PM2/22/15
to std-pr...@isocpp.org


On Sunday, February 22, 2015 at 4:42:22 AM UTC-5, Vicente J. Botet Escriba wrote:
 
I propose
* to use id instead of identity to avoid the backward compatibility constraint and
* to remove the operator() from id<T> as it is not really needed, id<>{} is the identity function object.

Would the following
be less controversial

template <class T=void>
struct id {
  using type = T;
};

template <class T>
using id_t = typename id<T>::type;

template <>
struct id<void> {
  using type = void;
  template <class U>
  U&& operator(U&& u) { return forward<U>(u); }
};

The drawback is that to name the identity function we need id<>{}

std::plus<>{}, std::equal_to<>{}, std::less<>{}, etc..
Unfortunately, doing it any other way would be inconsistent.

I think it's actually kinda neat: we can merge the concepts of
meta-functions with function objects to create something that
serves both! I just wonder if the weirdness overcomes the
practicality, or if there are any other similar utilities that could
be useful.
  
 

An alternative is to place the id meta function on a meta namespace (As Eric's meta library [1] does) and define an id lambda function (constexpr function object) as Lousi's Hana library does [1]

namespace meta {

  template <class T>
   struct id {
    using type = T;
   };

   template <class T>
   using id_t = typename id<T>::type;

}

/* constexpr*/ auto id = [](auto&& x) { return forward<decltype(x)>(x); };

I think that would make sense if someone wanted to propose a
meta library, but would be pretty weak as a stand-alone. Though I'm
a little peeved that what I consider to be primitives can't be properly
implemented.

 Other than that, Niebler's library might be a good starting point.

Scott Prager

unread,
Feb 22, 2015, 1:37:04 PM2/22/15
to std-pr...@isocpp.org


On Sunday, February 22, 2015 at 10:01:04 AM UTC-5, Matthew Fioravante wrote:
"id" also commonly means identifier. The name could be misleading.

Though, I think that most programmers have enough of a math background
to know what the identity function is. Anyone who might think "id" means
"identifier" might also think the same of "identity".
 
Another possibility could be std::same<T> or maybe std::identical<T>

"same" and "identical" seem to imply a type relation; might be confused with
std::is_same. The only alternate name I can think of is maybe just call it
"type<T>", but that feels a little ambiguous.

rhalb...@gmail.com

unread,
Feb 22, 2015, 3:54:56 PM2/22/15
to std-pr...@isocpp.org
I like Walter E. Brown's naming of type_is<T> in his CppCon14 talk (slide 16)

Matthew Woehlke

unread,
Feb 23, 2015, 10:42:19 AM2/23/15
to std-pr...@isocpp.org
On 2015-02-22 04:42, Vicente J. Botet Escriba wrote:
> I propose
> * to use id instead of identity to avoid the backward compatibility
> constraint

"Id" is *massively* used colloquially to mean "identification"... try
asking yourself how often you *don't* hear people substitute "id" when
they mean "identification" :-). In programming, it tends to mean instead
"identifier", although that's essentially the same idea.

Even though we *are* talking the same root as "identity", "identity" is
a specific mathematical term (and yes, I agree most programmers are
probably familiar with the mathematical meaning) that does not really
match up with what people think of as "identifiers".

That said, even "identity" is a bit broad of a concept, as there are
many possible "identities" (additive identity, multiplicative identity,
etc.).

It's (even) more typing, but what about type_identity?

(Too late now, but I find myself wondering if all these type transforms
shouldn't have been in their own namespace to differentiate them from
other operations...)

--
Matthew

Matthew Fioravante

unread,
Feb 24, 2015, 12:38:30 PM2/24/15
to std-pr...@isocpp.org, mw_t...@users.sourceforge.net


On Monday, February 23, 2015 at 10:42:19 AM UTC-5, Matthew Woehlke wrote:
On 2015-02-22 04:42, Vicente J. Botet Escriba wrote:
> I propose
> * to use id instead of identity to avoid the backward compatibility
> constraint

"Id" is *massively* used colloquially to mean "identification"... try
asking yourself how often you *don't* hear people substitute "id" when
they mean "identification" :-). In programming, it tends to mean instead
"identifier", although that's essentially the same idea.

I agree. Probably the majority of C++ applications I've written in my lifetime have had a for loop with an int id in it. I've also used id as a class type to wrap an integer indetifier in a type safe way. Basically whenever I see the "id" in code my mind is immediately thinking of names, strings, integers, identifiers for objects, for loops, etc..

Even though we *are* talking the same root as "identity", "identity" is
a specific mathematical term (and yes, I agree most programmers are
probably familiar with the mathematical meaning) that does not really
match up with what people think of as "identifiers".

That said, even "identity" is a bit broad of a concept, as there are
many possible "identities" (additive identity, multiplicative identity,
etc.).
 
It's (even) more typing, but what about type_identity?

Or maybe a shorthand

std::ident<T>

Tony V E

unread,
Feb 24, 2015, 3:03:02 PM2/24/15
to Standard Proposals
On Tue, Feb 24, 2015 at 12:38 PM, Matthew Fioravante <fmatth...@gmail.com> wrote:


Or maybe a shorthand

std::ident<T>

--


Obviously std::identi<T>.  (pronounced as "identi T" or "identity".
:-)

Tony

Reply all
Reply to author
Forward
0 new messages