Anyone else think that a std::has_member would be useful?

491 views
Skip to first unread message

Evan Teran

unread,
Oct 22, 2013, 11:56:35 PM10/22/13
to std-pr...@isocpp.org
I'm new to the forum so forgive me if this has been discussed in the past. I was  reading about new C++14 template constraints and other work with compile time reflection, and I thought that there may be a relatively simple mechanism which could be very useful in these categories.

What I am thinking is something like this:

std::has_member<&T::member, int(int)>::value

I'm not settled on has_member, perhaps "is_callable" would be a better fit, but that's an unimportant detail.

The idea being to test if there is a function in T, named "member" which has a signature matching "int member(int)". I believe that this would be require special compile support since if T::member doesn't exist, it would of course normally be compiler error to write things like &T::member.

The idea isn't quite fleshed out in my mind of how it could/should be implemented while still keeping with the spirit of C++, but I do feel that in general, the ability to test for the existence of a class member could be monumentally useful. It would allow things like:

* using static asserts to get better compiler errors when types are missing operators/member functions
* it would allow using enable_if to select a template specialization based on what a class supports which I think has interesting potential

Thoughts, Criticisms and Improvements are all welcome :-)

Evan

J. Daniel Garcia

unread,
Oct 23, 2013, 4:27:34 AM10/23/13
to std-pr...@isocpp.org
Hi Eva,

What would be the use cases.

In particular, are all the use cases for this feature in generic contexts? Or did you find some intersting use case in non generic contexts?
--
  J. Daniel


What I am thinking is something like this:

std::has_member<&T::member, int(int)>::value

I'm not settled on has_member, perhaps "is_callable" would be a better fit, but that's an unimportant detail.

The idea being to test if there is a function in T, named "member" which has a signature matching "int member(int)". I believe that this would be require special compile support since if T::member doesn't exist, it would of course normally be compiler error to write things like &T::member.

The idea isn't quite fleshed out in my mind of how it could/should be implemented while still keeping with the spirit of C++, but I do feel that in general, the ability to test for the existence of a class member could be monumentally useful. It would allow things like:

* using static asserts to get better compiler errors when types are missing operators/member functions
* it would allow using enable_if to select a template specialization based on what a class supports which I think has interesting potential

Thoughts, Criticisms and Improvements are all welcome :-)

Evan

--
 
---
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/.

Ville Voutilainen

unread,
Oct 23, 2013, 4:56:46 AM10/23/13
to std-pr...@isocpp.org
I have written custom traits for this sort of thing many times. The feature itself would be
quite useful.

Concepts lite seems to cover it, I can write

template <class T> concept bool has_f_member()
{
  return requires(T x) {x.f();};
}

with the current concepts branch of gcc.

J. Daniel Garcia

unread,
Oct 23, 2013, 4:59:07 AM10/23/13
to std-pr...@isocpp.org
That was the rationale behind my question.

Concepts lite covers the issue in generic contexts.

I was wondering if there might be any use case in non-generic contexts. I think the answer should be no. But I am not quite sure.

--
  J. Daniel

--

Ville Voutilainen

unread,
Oct 23, 2013, 5:10:15 AM10/23/13
to std-pr...@isocpp.org
On 23 October 2013 11:59, J. Daniel Garcia <josedani...@uc3m.es> wrote:
That was the rationale behind my question.

Concepts lite covers the issue in generic contexts.

I was wondering if there might be any use case in non-generic contexts. I think the answer should be no. But I am not quite sure.



Well, concepts lite probably covers it for non-generic contexts as well. :) I suppose I could write the
'requires' into a non-template. Not sure though, since that ICEs the implementation. :D

Evan Teran

unread,
Oct 23, 2013, 12:36:47 PM10/23/13
to std-pr...@isocpp.org
Yes, it seems that Concepts lite covers the use cases I was thinking of very well.

Now that I know more about it, i am looking forward to playing with it in C+14!

Thanks for the feedback.

Evan

Sebastian Gesemann

unread,
Oct 24, 2013, 4:38:39 AM10/24/13
to std-pr...@isocpp.org
On Wed, Oct 23, 2013 at 5:56 AM, Evan Teran <evan....@gmail.com> wrote:
> I'm new to the forum so forgive me if this has been discussed in the past. I
> was reading about new C++14 template constraints and other work with
> compile time reflection, and I thought that there may be a relatively simple
> mechanism which could be very useful in these categories.
>
> What I am thinking is something like this:
>
> std::has_member<&T::member, int(int)>::value

Just for completeness, I'd like to mention that "SFINAE" has gotten
better in C++11:

template<class T>
auto begin(T& x) -> decltype(x.begin())
{ return x.begin(); }

If there is no non-static member function T::begin, the return type
cannot be deduced and the template is simply ignored. So, this would
be a kind of "implicit constraining". There is no need to write a
requires clause or an enable_if for that:

template<class T>
requires(has_member<....>()) <-- kind of redundant
auto begin(T& x) -> decltype(x.begin())
{ return x.begin(); }

Cheers!
SG
Reply all
Reply to author
Forward
0 new messages