constexpr

Why should I prefer static constexpr int in a class over enum for class-level integral constants?

送分小仙女□ 提交于 2019-12-03 12:55:14
C++17 Update: static constexpr variables are implicitly inline so there's no external definition necessary. Original question: Let's say I have a list of constants such as struct Cls { static constexpr int N = 32; static constexpr int M = 64; }; This of course suggests that I add definitions for these to avoid ODR-usage issues that may occur so I need: constexpr int Cls::N; constexpr int Cls::M; Why should I prefer this over struct Cls { enum : int { N = 32, M = 64 }; }; Which saves me of the ODR-usage headaches since N and M are more truly just constants and not objects in their own right (a

simulate compile time reflection in C++

主宰稳场 提交于 2019-12-03 12:54:09
I have a following struct: struct Data { std::string firstMember; std::string secondMember; std::string thirdMember; }; I want to select one of the members by string name in constexpr manner, like Data instance; auto& member = getMember(instance, "firstMember"); getMember is constexpr function/struct/macros/whatever in question and expression should be (I want it to be) optimized into simple auto& member = instance.firstMember; . My desire here is to be able to call getMember from another constexpr function, which in turn are computing name of particular member --> some kind of compile time

As far as I can tell the function below is not constexpr, but the code compiles in clang and g++. What am I missing?

允我心安 提交于 2019-12-03 12:02:11
I got this example from §5.19/2 in N4140: constexpr int incr(int &n) { return ++n; } As far as I can tell, this is not a constexpr function. But the snippet compiles in clang and g++. See live example . What am I missing here? In C++14 the rules for constexpr function were relaxed and the paper N3597: Relaxing constraints on constexpr functions . The paper goes into the rationale and the effects and it includes the following ( emphasis mine ): As in C++11, the constexpr keyword is used to mark functions which the implementation is required to evaluate during translation, if they are used from

Initializing constexpr with const: Different treatment for int and double

允我心安 提交于 2019-12-03 11:40:20
The following code fails to compile live on Ideone : #include <iostream> using namespace std; int main() { const double kPi = 3.14; constexpr double kPi2 = 2.0*kPi; cout << kPi2; } The error message is: prog.cpp: In function 'int main()': prog.cpp:6:30: error: the value of 'kPi' is not usable in a constant expression constexpr double kPi2 = 2.0*kPi; ^ prog.cpp:5:15: note: 'kPi' was not declared 'constexpr' const double kPi = 3.14; Substituting the const declaration for kPi with constexpr , it compiles successfully . On the other hand, when int is used instead of double , seems like const plays

Cannot construct constexpr array from braced-init-list

[亡魂溺海] 提交于 2019-12-03 11:40:02
问题 I've implemented a constexpr array like this: template <typename T> class const_array { const T* p; unsigned n; public: template <unsigned N> constexpr const_array(const T(&a)[N]): p(a), n(N) { } constexpr unsigned size() const { return n; } }; int main(int argc, char* argv[]) { // works static_assert(const_array<double>{{1.,2.,3.}}.size() == 3); // doesn't compile constexpr const_array<double> a{{1.,2.,3.}}; static_assert(a.size() == 3); } Why is it that the first static_assert compiles, but

Why isn't constexpr implied when applicable?

孤街醉人 提交于 2019-12-03 10:45:49
These should probably be in different questions, but they're related so... Why do we need to write constexpr at all? Given a set of restrictions couldn't a compiler evaluate code to see if it satisfies the constexpr requirements, and treat it as constexpr if it does? As a purely documentation keyword I'm not sure it holds up because I can't think of a case where I (the user of someone else's constexpr function) should really care if it's run time or not. Here's my logic: If it's an expensive function I think as a matter of good practice I should treat it as such regardless of whether I give it

Confusion about constant expressions

孤者浪人 提交于 2019-12-03 10:30:45
This is some kind of follow-up for this topic and deals about a little part of it. As with the previous topic, let's consider that our compiler has constexpr functions for std::initializer_list and std::array . Now, let's go straight to the point. This works : #include <array> #include <initializer_list> int main() { constexpr std::array<int, 3> a = {{ 1, 2, 3 }}; constexpr int a0 = a[0]; constexpr int a1 = a[1]; constexpr int a2 = a[2]; constexpr std::initializer_list<int> b = { a0, a1, a2 }; return 0; } This does not : #include <array> #include <initializer_list> int main() { constexpr std:

Can virtual functions be constexpr?

核能气质少年 提交于 2019-12-03 10:16:20
Can virtual functions like X::f() in the following code struct X { constexpr virtual int f() const { return 0; } }; be constexpr ? Kerrek SB This answer is no longer correct as of C++20. No. From [dcl.constexpr]/3 (7.1.5, "The constexpr specifier"): The definition of a constexpr function shall satisfy the following requirements: — it shall not be virtual Up through C++17, virtual functions could not be declared constexpr . The general reason being that, in constexpr code, everything happen can at compile time. So there really isn't much point to having a function which takes a reference to a

C++ constexpr function in return statement

笑着哭i 提交于 2019-12-03 09:53:20
Why is a constexpr function no evaluated at compile time but in runtime in the return statement of main function? It tried template<int x> constexpr int fac() { return fac<x - 1>() * x; } template<> constexpr int fac<1>() { return 1; } int main() { const int x = fac<3>(); return x; } and the result is main: push rbp mov rbp, rsp mov DWORD PTR [rbp-4], 6 mov eax, 6 pop rbp ret with gcc 8.2. But when I call the function in the return statement template<int x> constexpr int fac() { return fac<x - 1>() * x; } template<> constexpr int fac<1>() { return 1; } int main() { return fac<3>(); } I get int

Equivalent ternary operator for constexpr if?

↘锁芯ラ 提交于 2019-12-03 09:31:06
Maybe I missed something, but I can't find any hints: is there a constexpr ternary operator in C++17 equivalent to constexpr-if? template<typename Mode> class BusAddress { public: explicit constexpr BusAddress(Address device) : mAddress(Mode::write ? (device.mDevice << 1) : (device.mDevice << 1) | 0x01) {} private: uint8_t mAddress = 0; }; No, there is no constexepr conditional operator. But you could wrap the whole thing in a lambda and immediately evaluate it (an IIFE ): template<typename Mode> class BusAddress { public: explicit constexpr BusAddress(Address device) : mAddress([&]{ if