Can we define a concept for tuple-like types?

103 views
Skip to first unread message

Vicente J. Botet Escriba

unread,
Feb 26, 2017, 7:54:33 AM2/26/17
to conc...@isocpp.org

While reading P0589R0, I had the impression that we are unable to define a concept for tuple-like types

I have tried and of course I have not reached.

    http://melpon.org/wandbox/permlink/40vYx3K8tFtopwif

From the error report, it seems that there are no short-cuts for operator &&  and ||.

I have also tried with "if constexpr" without success. Can we use "if constexpr"inside concept definitions?

Do you confirm that we are unable to define a TupleLike concept if we want to check for get<I>(tpl) for I in 0..std::tuple_size_v<T>-1?

If not, how we can define it?

Vicente



Vicente J. Botet Escriba

unread,
Feb 26, 2017, 8:48:30 AM2/26/17
to conc...@isocpp.org
It seems that we can not use recursion while defining concepts. Without recursion, I don't see how we could define a TupleLike concept.

However I would expect that the && short-cut is applied in the following example and std::tuple_element_t<-1, PT> is not evaluated

template <unsigned N, typename PT>
concept bool TupleLikeN ()
{
    return ( N>0 
           && requires (PT pt)
            {
                typename std::tuple_element_t<N-1, PT>;
                { std::get<N-1>(pt) } -> std::tuple_element_t<N-1, PT>;
            }
        );
}

static_assert(   ! TupleLikeN<1,std::tuple<>>()    , "error");

http://melpon.org/wandbox/permlink/CLKZU7O1SeSgrRJU

Is there a way to define this concept?

Vicente

Vicente J. Botet Escriba

unread,
Feb 26, 2017, 9:23:50 AM2/26/17
to conc...@isocpp.org
Le 26/02/2017 à 14:48, Vicente J. Botet Escriba a écrit :
Le 26/02/2017 à 13:54, Vicente J. Botet Escriba a écrit :

While reading P0589R0, I had the impression that we are unable to define a concept for tuple-like types

I have tried and of course I have not reached.

    http://melpon.org/wandbox/permlink/40vYx3K8tFtopwif

From the error report, it seems that there are no short-cuts for operator &&  and ||.

I have also tried with "if constexpr" without success. Can we use "if constexpr"inside concept definitions?

Do you confirm that we are unable to define a TupleLike concept if we want to check for get<I>(tpl) for I in 0..std::tuple_size_v<T>-1?

If not, how we can define it?


It seems that we can not use recursion while defining concepts. Without recursion, I don't see how we could define a TupleLike concept.
Hmm, wait, we have clasic template meta-programming


With TMP, we can avoid unwanted evaluations and use recursion :)

The code is not very clean but I would say it works.

    http://melpon.org/wandbox/permlink/7JgrcFZPfsCh1xVk


Vicente

P.S. Any elegant definition is welcome

Andrew Sutton

unread,
Feb 26, 2017, 9:38:40 AM2/26/17
to conc...@isocpp.org

While reading P0589R0, I had the impression that we are unable to define a concept for tuple-like types

I have tried and of course I have not reached.

    http://melpon.org/wandbox/permlink/40vYx3K8tFtopwif

From the error report, it seems that there are no short-cuts for operator &&  and ||.

I have also tried with "if constexpr" without success. Can we use "if constexpr"inside concept definitions?

Do you confirm that we are unable to define a TupleLike concept if we want to check for get<I>(tpl) for I in 0..std::tuple_size_v<T>-1?

If not, how we can define it?


It seems that we can not use recursion while defining concepts. Without recursion, I don't see how we could define a TupleLike concept.

Allowing recursive concepts (and concept specialization) makes partial ordering undecidable. You can define the concept using a type trait.

But... since I wrote the tuple-for loop proposal, I had to think about this also. I would like to say that for a reasonable implementation of a tuple-like class and all integers N, the call get<N>(t) should be resolved. It may result in a static_assertion when called, but we should still be able to find a declaration.

I'm not sure that's reasonable. There are lots of things that an implementer may do with get<N>():
- Use concepts to disable specializations for out-of-bounds N,
- delete specializations for out-of-bounds N,
- use return-type deduction.
All of those will break the check.

This holds for element_type, too.

So, the only thing I can think to check is if tuple_size<> is specialized. You could write the concept in way that:
1. Checks for constexpr int N = tuple_size<T>,
2. Evaluates a trait that attempts to resolve get<I>(t) for each I in [0, N).

The for-loop proposal just checks for tuple_size<T> and if any get<I>(t) fails during loop body instantiation, the program is ill-formed.


 
You received this message because you are subscribed to the Google Groups "SG8 - Concepts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to concepts+u...@isocpp.org.
To post to this group, send email to conc...@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/concepts/.
--
Andrew Sutton

Andrew Sutton

unread,
Feb 26, 2017, 9:40:15 AM2/26/17
to conc...@isocpp.org
Hmm, wait, we have clasic template meta-programming


With TMP, we can avoid unwanted evaluations and use recursion :)

That's what I would do :) I suggested it in the email I was writing while you sent this. Race conditions!

Off to board my first flight to Kona.

--
Andrew Sutton

Vicente J. Botet Escriba

unread,
Feb 26, 2017, 10:17:47 AM2/26/17
to conc...@isocpp.org
Le 26/02/2017 à 15:38, Andrew Sutton a écrit :

While reading P0589R0, I had the impression that we are unable to define a concept for tuple-like types

I have tried and of course I have not reached.

    http://melpon.org/wandbox/permlink/40vYx3K8tFtopwif

From the error report, it seems that there are no short-cuts for operator &&  and ||.

I have also tried with "if constexpr" without success. Can we use "if constexpr"inside concept definitions?

Do you confirm that we are unable to define a TupleLike concept if we want to check for get<I>(tpl) for I in 0..std::tuple_size_v<T>-1?

If not, how we can define it?


It seems that we can not use recursion while defining concepts. Without recursion, I don't see how we could define a TupleLike concept.

Allowing recursive concepts (and concept specialization) makes partial ordering undecidable. You can define the concept using a type trait.
Thanks for explanation. I believe I understand the problem.


But... since I wrote the tuple-for loop proposal, I had to think about this also. I would like to say that for a reasonable implementation of a tuple-like class and all integers N, the call get<N>(t) should be resolved. It may result in a static_assertion when called, but we should still be able to find a declaration.
Why do you need for all the integers N. I believed that it was undefined what get<I>(tpl) does for I out of [0,N).


I'm not sure that's reasonable. There are lots of things that an implementer may do with get<N>():
- Use concepts to disable specializations for out-of-bounds N,
- delete specializations for out-of-bounds N,
- use return-type deduction.
All of those will break the check.

This holds for element_type, too.

So, the only thing I can think to check is if tuple_size<> is specialized.

You could write the concept in way that:
1. Checks for constexpr int N = tuple_size<T>,
2. Evaluates a trait that attempts to resolve get<I>(t) for each I in [0, N).

Yes, this is what I did. Thanks anyway.

The for-loop proposal just checks for tuple_size<T> and if any get<I>(t) fails during loop body instantiation, the program is ill-formed.

I understand that you don't need to check get<I>(t), but you have not responded to my last question on the other mail
> It is weird that we wouldn't have a concept for the type supported by this tuple-based for loop, and that only the std::tuple_size is checked. In addition, 
> I believe that the types supported should be any type supported by structured binding.

Why not for all the types supported by structure binding?

Another question I raised is about the short-cuts for && nad ||. Can them be used and if not why? decidability also?


Vicente
Reply all
Reply to author
Forward
0 new messages