if-constexpr

Do I need to put constexpr after else-if?

故事扮演 提交于 2019-12-17 23:33:31
问题 Inspired by this answer, I tried to copy and paste (and add testing in main() ) this code: template<typename T> std::tuple<int, double> foo(T a) { if constexpr (std::is_same_v<int, T>) return {a, 0.0}; else if (std::is_same_v<double, T>) return {0, a}; else return {0, 0.0}; } int main() { auto [x, y] = foo(""); std::cout << x << " " << y; } This is very straightforward - if T is deduced as int , we want to return a tuple of [a, 0.0] . If T is deduced as double , we want to return a tuple of

if vs if constexpr inside constexpr function

可紊 提交于 2019-12-13 14:21:12
问题 Recently I modify some if constexpr into if in my constexpr functions and found they still work fine and can be evaluated when compile time. Here is a minimum case: template<int N> constexpr bool is_negative() { if constexpr (N >= 0) return false; else return true; } int main() { constexpr bool v = is_negative<1>(); } live demo In the case above, N must be known at compile time because it is non-type template parameter, so if constexpr works fine here. However, it is a constexpr function, so,

Constexpr if with non-template types

白昼怎懂夜的黑 提交于 2019-12-10 17:17:08
问题 #include <iostream> int foo(int x) { if constexpr (std::is_same_v<decltype(x), std::string>) { x = std::string(); } } int main(void) { return 0; } This code doesn't compile on either GCC 7 nor Clang 5: error: cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘int’ in assignment x = std::string(); Since the referenced line is in a constexpr if branch that should evaluate to false , shouldn't the program compile fine? 回答1: The if constexpr specification defines the

if constexpr instead of tag dispatch

≡放荡痞女 提交于 2019-12-10 05:45:14
问题 I want to use if constexpr instead of tag dispatching, but I am not sure how to use it. Example code below. template<typename T> struct MyTag { static const int Supported = 0; }; template<> struct MyTag<std::uint64_t> { static const int Supported = 1; }; template<> struct MyTag<std::uint32_t> { static const int Supported = 1; }; class MyTest { public: template<typename T> void do_something(T value) { // instead of doing this bool supported = MyTag<T>::Supported; // I want to do something like

False-branch of if constexpr not discarded in templated lambda

爱⌒轻易说出口 提交于 2019-12-10 02:17:23
问题 I have a problem with "if constexpr" in a templated lambda. For the sake of argument let's ignore how I got there, but I have a struct foo that is defined in some way to result in something as follows: template<bool condition> struct foo { int a; // Only contains b if condition is true int b; } Now I can define a templated function thtemplate template<bool condition> void print_fun(foo & obj) { /* Do something with obj.a */ if constexpr(condition) /* Do something with obj.b */ };

Can constexpr-if-else bodies return different types in constexpr auto function?

ぐ巨炮叔叔 提交于 2019-12-07 09:08:50
问题 I'm trying to write a function that maps an enumeration of values to a set of types based on the runtime value of the enumeration. I realize that you cannot return different types based on the runtime value of an enumeration because the compiler wouldn't know how much stack space to allocate. However I'm trying to write this as a constexpr function, using the new if-constexpr functionality to implement this. I'm getting an error from clang complaining that I'm using an illegally specified

Can constexpr-if-else bodies return different types in constexpr auto function?

戏子无情 提交于 2019-12-05 15:34:05
I'm trying to write a function that maps an enumeration of values to a set of types based on the runtime value of the enumeration. I realize that you cannot return different types based on the runtime value of an enumeration because the compiler wouldn't know how much stack space to allocate. However I'm trying to write this as a constexpr function, using the new if-constexpr functionality to implement this. I'm getting an error from clang complaining that I'm using an illegally specified template parameter. Does anyone see how to implement this? edit: Here is an easier to grok version

if constexpr instead of tag dispatch

守給你的承諾、 提交于 2019-12-05 09:58:51
I want to use if constexpr instead of tag dispatching, but I am not sure how to use it. Example code below. template<typename T> struct MyTag { static const int Supported = 0; }; template<> struct MyTag<std::uint64_t> { static const int Supported = 1; }; template<> struct MyTag<std::uint32_t> { static const int Supported = 1; }; class MyTest { public: template<typename T> void do_something(T value) { // instead of doing this bool supported = MyTag<T>::Supported; // I want to do something like this if constexpr (T == std::uint64_t) supported = true; } }; One way is to define a constexpr

False-branch of if constexpr not discarded in templated lambda

女生的网名这么多〃 提交于 2019-12-05 01:18:15
I have a problem with "if constexpr" in a templated lambda. For the sake of argument let's ignore how I got there, but I have a struct foo that is defined in some way to result in something as follows: template<bool condition> struct foo { int a; // Only contains b if condition is true int b; } Now I can define a templated function thtemplate template<bool condition> void print_fun(foo & obj) { /* Do something with obj.a */ if constexpr(condition) /* Do something with obj.b */ }; Instantiating this function and using it will compile, if the constexpr parameter to foo is the same as the one to

std::is_constant_evaluated behavior

放肆的年华 提交于 2019-12-04 22:51:18
GCC9 already implements std::is_constant_evaluated . I played a little bit with it, and I realized it is somewhat tricky. Here’s my test: constexpr int Fn1() { if constexpr (std::is_constant_evaluated()) return 0; else return 1; } constexpr int Fn2() { if (std::is_constant_evaluated()) return 0; else return 1; } int main() { constexpr int test1 = Fn1(); // Evaluates to 0 int test2 = Fn1(); // Evaluates to 0 int const test3 = Fn1(); // Evaluates to 0 constexpr int test4 = Fn2(); // Evaluates to 0 int test5 = Fn2(); // Evaluates to 1 int const test6 = Fn2(); // Evaluates to 0 } According to