switch constexpr

4,833 views
Skip to first unread message

Elias Kosunen

unread,
Jul 10, 2017, 12:00:43 PM7/10/17
to ISO C++ Standard - Future Proposals
With the introduction of if constexpr in C++17, I was wondering if we could also extend the same behavior to switch-statements. I think it would fit well in the language and simplify complicated compile-time branching.
It would also enable compile-time usage of the C++ Core Guideline ES.70 (
Prefer a switch-statement to an if-statement when there is a choice)

For example:

template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
int do_integer() {
   
// if constexpr
   
if constexpr (sizeof(T) == 1) {
       
return do_i8();
   
} else if constexpr (sizeof(T) == 2) {
       
return do_i16();
   
} else if constexpr (sizeof(T) == 4) {
       
return do_i32();
   
} else if constexpr (sizeof(T) == 8) {
       
return do_i64();
   
} else {
       
// We *shouldn't* get here
   
}

   
// Simplified with switch constexpr
   
switch constexpr (sizeof(T)) {
       
case 1: return do_i8();
       
case 2: return do_i16();
       
case 4: return do_i32();
       
case 8: return do_i64();
       
default: // Is there any architecture with other-sized integers?
   
}
}

Even in that relatively simple example, the switch-method, in my opinion, is clearer and more expressive.

Surprisingly, I couldn't find any discussion in this regard. Should there be any, please point me to it.

- Elias

Zhihao Yuan

unread,
Jul 10, 2017, 2:30:45 PM7/10/17
to std-pr...@isocpp.org
On Mon, Jul 10, 2017 at 11:00 AM, Elias Kosunen <elias....@gmail.com> wrote:


template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
int do_integer() {
   
// if constexpr
   
if constexpr (sizeof(T) == 1) {
       
return do_i8();
   
} else if constexpr (sizeof(T) == 2) {
       
return do_i16();
   
} else if constexpr (sizeof(T) == 4) {
       
return do_i32();
   
} else if constexpr (sizeof(T) == 8) {
       
return do_i64();
   
} else {
       
// We *shouldn't* get here
   
}

   
// Simplified with switch constexpr
   
switch constexpr (sizeof(T)) {
       
case 1: return do_i8();
       
case 2: return do_i16();
       
case 4: return do_i32();
       
case 8: return do_i64();
       
default: // Is there any architecture with other-sized integers?
   
}
}

Even in that relatively simple example, the switch-method, in my opinion, is clearer and more expressive.

Selectively instantiating overlapping scopes are
unnessasrily complex, since switch statements
support fallthrough.  Beyond that, switch statements
doesn't support examining user-defined literal types,
making `switch constexpr` less useful.
 

Surprisingly, I couldn't find any discussion in this regard. Should there be any, please point me to it.


The idea here is simple if you understand C11
generic selection expressions.

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

Ray Hamel

unread,
Jul 10, 2017, 6:04:53 PM7/10/17
to ISO C++ Standard - Future Proposals
For consistency and flexibility's sake, perhaps constexpr versions of for, while, and do-while statements should also be added at the same time?

Michał Dominiak

unread,
Jul 10, 2017, 7:42:02 PM7/10/17
to ISO C++ Standard - Future Proposals
Those have a very different compile time complexities and will be handled separately by SG7.

On Mon, Jul 10, 2017 at 6:04 PM Ray Hamel <rayg...@gmail.com> wrote:
For consistency and flexibility's sake, perhaps constexpr versions of for, while, and do-while statements should also be added at the same time?

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/25e84110-5b8b-471d-a72b-2ed5b63f4865%40isocpp.org.

Elias Kosunen

unread,
Jul 12, 2017, 2:39:44 PM7/12/17
to ISO C++ Standard - Future Proposals
I considered them as well, but I think their semantics wouldn't be as obvious as it is for if and switch.

Ray Hamel

unread,
Jul 12, 2017, 3:58:39 PM7/12/17
to ISO C++ Standard - Future Proposals
Yes, thinking about it a little more it's a tricky subset of the halting problem to determine at compile time whether a loop is (or might be) infinite. Although I think this capability might already be required of conforming implementations?

constexpr void loop(int i) {while (i++);}
// GCC, VS & ICC currently return true if loop provably finite, false otherwise
// Clang always returns false
noexcept
(loop(foo))

-Ray
Reply all
Reply to author
Forward
0 new messages