explicit underlying type conversion used in integral switch contexts.

86 views
Skip to first unread message

Vicente J. Botet Escriba

unread,
Apr 26, 2017, 3:58:59 PM4/26/17
to std-pr...@isocpp.org

Hi,


we have that instances of types with an explicit conversion to bool can be used in if statements, with logical operators &&, ||, and ! and with the ?: operator.


When we have strong type wrapping integers, we need to provide access to the underlying type and very often it is provided using an explicit conversion.

However when we use a strong type in a switch we must use the access function or cast it to the integer, as in

    switch (st.value()) {

    ...

or

    switch (int(st)) {

    ...

or

    switch (underlying(st)) {

    ...

where underlying is a function that do the cast to the underlying type.

I was wondering if we can not extend the switch statement. It could accept any type convertible to an integral type (a type that can be in a switch condition). If more than one of these conversion is possible then the program will not be well formed.

switch (st) {

...


This could be useful where you have some generic code expecting an Integral type.

template <class Integral>
void f(Integral i)
{

    switch (i) {

    ...
}

This code will not compile if we pass it a strong integer type wrapping an int. We would need to define a underlying function that works for enums, int and strong integer types e.g.

template <class Integral>
void f(Integral i)
{

    switch (underlying(i)) {

    ...
}

I'm expecting that we will have more and more strong types, as e.g. day, month, weekday, and other existing types as duration. We are now forced to call to a function in this context which seams redundant.

What do you think about calling to the explicit conversion in this context?
Is it worth changing the C++ standard language for this specific case?

If not do we want to have the possibility to specialize the underlying_type trait and add the underlying function?

Would the future pattern matching help on this concern? and how?

Vicente


Vicente J. Botet Escriba

unread,
Apr 26, 2017, 4:16:37 PM4/26/17
to std-pr...@isocpp.org
After thinking more about this it could be better if the case statements accepted constants of the strong type as well

    using subframe = bounded_integer<int, 0, 9>

    switch (sf) // implicit conversion using explicit int(bi)

    {

    case subframe{0}: ...

    case subframe{1}: ...

    default:

    }


or

    weekday wd = ...
    switch (wd) {
    case saturday: ...
    case sunday: ...
    default:
    }

Having to define builtin integral constants associated to the underlying values for the day literals would be cumbersome

    weekday wd = ...
    switch (unsigned(wd)) {
    case SATURDAY: ...
    case SUNDAY: ...
    default:
    }

The UPPER_CASE intend to be the integral constants.

Not having them will imply code that could be less readable using chained if

if (saturday==wd)
    ....
else if (saunday==wd)

or even worst using directly the magic number of underlying value

    weekday wd = ...
    switch (unsigned(wd)) {
    case 6: ...
    case 0: ...
    default:
    }

Vicente

Zhihao Yuan

unread,
Apr 26, 2017, 4:25:24 PM4/26/17
to std-pr...@isocpp.org
On Wed, Apr 26, 2017 at 1:16 PM, Vicente J. Botet Escriba
<vicent...@wanadoo.fr> wrote:
> After thinking more about this it could be better if the case statements
> accepted constants of the strong type as well
>
> using subframe = bounded_integer<int, 0, 9>
>
> switch (sf) // implicit conversion using explicit int(bi)
>
> {
>
> case subframe{0}: ...
>
> case subframe{1}: ...
>
> default:
>
> }

Does

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3627.html

meet your demand? (This paper requires your strong
types to define constexpr == and <).

--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
_______________________________________________

Vicente J. Botet Escriba

unread,
Apr 27, 2017, 1:47:05 AM4/27/17
to std-pr...@isocpp.org
Le 26/04/2017 à 22:25, Zhihao Yuan a écrit :
> On Wed, Apr 26, 2017 at 1:16 PM, Vicente J. Botet Escriba
> <vicent...@wanadoo.fr> wrote:
>> After thinking more about this it could be better if the case statements
>> accepted constants of the strong type as well
>>
>> using subframe = bounded_integer<int, 0, 9>
>>
>> switch (sf) // implicit conversion using explicit int(bi)
>>
>> {
>>
>> case subframe{0}: ...
>>
>> case subframe{1}: ...
>>
>> default:
>>
>> }
> Does
>
> http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3627.html
>
> meet your demand? (This paper requires your strong
> types to define constexpr == and <).
>
Yes it does. What is the status of this proposal?


Vicente

Zhihao Yuan

unread,
Apr 27, 2017, 2:17:02 PM4/27/17
to std-pr...@isocpp.org
On Thu, Apr 27, 2017 at 12:47 AM, Vicente J. Botet Escriba
<vicent...@wanadoo.fr> wrote:
>>
> Yes it does. What is the status of this proposal?

EWG wants some design making std::string
matching against string literals cases work
out of the box (currently this paper requires
casting std::string into std::string_view), and
I don't have a good way to naturally satisfy
this requirement. Maybe you can help :)

Dan Raviv

unread,
Apr 27, 2017, 3:41:58 PM4/27/17
to ISO C++ Standard - Future Proposals, z...@miator.net
Hi Zhihao,

IIUC the problem is just that operator==() for std::string isn't constexpr? (whereas it is constexpr for std::string_view). Or is there any other issue?

Cheers,
Dan

Zhihao Yuan

unread,
Apr 27, 2017, 5:16:16 PM4/27/17
to Dan Raviv, ISO C++ Standard - Future Proposals, Zhihao Yuan
On Thu, Apr 27, 2017 at 2:41 PM, Dan Raviv <dan....@gmail.com> wrote:
> IIUC the problem is just that operator==() for std::string isn't constexpr?
> (whereas it is constexpr for std::string_view).

Yes, plus operator<.

There can be another interpretation, that is we
lack information to compare raw string literals
other than converting them to std::string_view.

Zhihao Yuan

unread,
Apr 27, 2017, 5:36:19 PM4/27/17
to Dan Raviv, Zhihao Yuan, std-pr...@isocpp.org
On Thu, Apr 27, 2017 at 4:24 PM, Dan Raviv <dan....@gmail.com> wrote:
> Ok, and is there a good reason why operator==() for std::string isn't
> constexpr? (other than it hasn't made it into the standard yet?)

It's the reason for the current proposal not able
to directly switch (/* std::string */) but it's not
the reason for why we want
std::string::operator== to be constexpr. These
two issues are not inherently dependent from
one to the other. Consider looking for a
std::string in a sequence of std::string_view,
operator== for std::string doesn't have to be
constexpr, for example, if we can deal with that
then it would benefit other types as well.

Vicente J. Botet Escriba

unread,
Apr 27, 2017, 5:56:13 PM4/27/17
to std-pr...@isocpp.org
Le 27/04/2017 à 20:16, Zhihao Yuan a écrit :
On Thu, Apr 27, 2017 at 12:47 AM, Vicente J. Botet Escriba
<vicent...@wanadoo.fr> wrote:

        
Yes it does. What is the status of this proposal?
EWG wants some design making std::string
matching against string literals cases work
out of the box (currently this paper requires
casting std::string into std::string_view), and
I don't have a good way to naturally satisfy
this requirement.  Maybe you can help :)

This is not the use case I was looking for, but anyway.

Sorry I'm missing surely something really important.

What is the problem with string? That we don't have string literals? Wouldn't require just an explicit conversion to string_view solve the issue?

Why not restrict it to string_view that is a literal?

Once we have constexpr_string we could as well relax the switch to this type.

Vicente

Vicente J. Botet Escriba

unread,
Apr 27, 2017, 5:58:53 PM4/27/17
to std-pr...@isocpp.org, z...@miator.net
Le 27/04/2017 à 21:41, Dan Raviv a écrit :
> Hi Zhihao,
>
> IIUC the problem is just that operator==() for std::string isn't
> constexpr? (whereas it is constexpr for std::string_view). Or is there
> any other issue?
>
Why would you like a constexpr operator== if you cannot have constexpr
strings to compare?

Vicente

Dan Raviv

unread,
Apr 27, 2017, 6:11:50 PM4/27/17
to std-pr...@isocpp.org
Indeed. Thanks.




--
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e3544184-af31-0c97-50d5-8ab4cac2a720%40wanadoo.fr.

Zhihao Yuan

unread,
Apr 27, 2017, 6:34:05 PM4/27/17
to std-pr...@isocpp.org
My understanding about string literals is that they
are initializers. Themselves do have types (array),
but these types may not convey information about
the objects they are going to initialize. string_view
or constexpr_string are not the the only types that
can be initialized from string literals, so that
string_view's ordering may be different from some
other destination types, basic_string_view<char,
CustomTraits> for example.
Reply all
Reply to author
Forward
0 new messages