constexpr

constexpr vs. static const: Which one to prefer?

↘锁芯ラ 提交于 2019-11-28 06:13:37
For defining compile-time constants of integral types like the following (at function and class scope), which syntax is best? static const int kMagic = 64; // (1) constexpr int kMagic = 64; // (2) (1) works also for C++98/03 compilers, instead (2) requires at least C++11. Are there any other differences between the two? Should one or the other be preferred in modern C++ code, and why? EDIT I tried this sample code with Godbolt's CE : int main() { #define USE_STATIC_CONST #ifdef USE_STATIC_CONST static const int kOk = 0; static const int kError = 1; #else constexpr int kOk = 0; constexpr int

Force constexpr to be evaluated at compile time

匆匆过客 提交于 2019-11-28 06:00:14
问题 #include <algorithm> struct S { static constexpr int X = 10; }; int main() { return std::min(S::X, 0); }; If std::min expects a const int& , the compiler very likely would like to have the S::X also defined somewhere, i.e. the storage of S::X must exists. See here or here. Is there a way to force the compiler to evaluate my constexpr at compile time? The reason is: Initially, we had a problem in early initialization of static variables in the init priority. There was some struct Type<int> {

Compile-time or runtime detection within a constexpr function

主宰稳场 提交于 2019-11-28 05:27:05
I was excited when constexpr was introduced in C++11, but I unfortunately made optimistic assumptions about its usefulness. I assumed that we could use constexpr anywhere to catch literal compile-time constants or any constexpr result of a literal compile-time constant, including something like this: constexpr float MyMin(constexpr float a, constexpr float b) { return a<b?a:b; } Because qualifying a function's return type only as constexpr does not limit its usage to compile-time, and must also be callable at runtime, I figured that this would be a way to ensure that MyMin can only ever be

Why isn't `std::initializer_list` defined as a literal type?

心不动则不痛 提交于 2019-11-28 04:49:38
This is a follow-up of this question: Is it legal to declare a constexpr initializer_list object? . Since C++14, the std::initializer_list class has all of its methods marked with constexpr . It seems natural to be able to initialize an instance by doing constexpr std::initializer_list<int> list = {1, 2, 3}; but Clang 3.5 complains about list not being initialized by a constant expression. As dyp pointed out in a comment , any requirement for std::initializer_list to be a literal type seem to have vanished from the specs. What's the point of having a class fully defined as constexpr if we can

constexpr array and std::initializer_list

青春壹個敷衍的年華 提交于 2019-11-28 04:49:30
问题 I was trying to write an compile-time valarray that could be used like this: constexpr array<double> a = { 1.0, 2.1, 3.2, 4.3, 5.4, 6.5 }; static_assert(a[0] == 1.0, ""); static_assert(a[3] == 4.3, ""); static_assert(a.size() == 6, ""); I managed to do it with the following implementation and it works fine (with GCC 4.7): #include <initializer_list> template<typename T> struct array { private: const std::size_t _size; const T* _data; public: constexpr array(std::initializer_list<T> values):

Undefined reference error for static constexpr member

*爱你&永不变心* 提交于 2019-11-28 02:37:25
问题 Consider this code: #include <vector> struct A { static constexpr int kDefaultValue = -1; std::vector<int> v; A(int n): v(n, A::kDefaultValue) {} }; int main() { A(10); return 0; } It fails to link (llvm clang, gcc 4.9, both on OS X): Undefined symbols for architecture x86_64: "A::kDefaultValue", referenced from: A::(int) in main.cpp.o ld: symbol(s) not found for architecture x86_64 The question is what's wrong with it? It can be fixed by static_cast -ing A::kDefaultValue to int . Or by

Initializing a static constexpr from an incomplete type because of a template base class

可紊 提交于 2019-11-28 01:28:19
I have a template base class, whereby subclasses are expected to pass themselves as the template parameter. It looks a little like this: template<typename T> struct Base { constexpr Base(int x) : m_x(x) {} private: int m_x; }; struct Derived : public Base<Derived> { static const Derived LIFE; constexpr Derived(int x) : Base(x) {} }; const Derived Derived::LIFE = Derived(42); That compiles and works as expected. But now I'd like to make Derived::LIFE a constexpr. Is this even possible? I can't just change it's const qualifier to constexpr, as a constexpr needs to be initialized in its

How to tell static_assert that constexpr function arguments are const?

老子叫甜甜 提交于 2019-11-28 00:12:03
问题 I have a constexpr function that looks something like this: constexpr int foo(int bar) { static_assert(bar>arbitrary_number, "Use a lower number please"); return something_const; } However, compiling this with GCC 4.6.3 keeps telling me error: 'bar' cannot appear in a constant-expression I tried something like constexpr int foo(constexpr const int bar) { static_assert(bar>arbitrary_number, "Use a lower number please"); return something_const; } but constexpr can't be used for function

C++11 constexpr function's argument passed in template argument

╄→гoц情女王★ 提交于 2019-11-27 23:24:18
问题 This used to work some weeks ago: template <typename T, T t> T tfunc() { return t + 10; } template <typename T> constexpr T func(T t) { return tfunc<T, t>(); } int main() { std::cout << func(10) << std::endl; return 0; } But now g++ -std=c++0x says: main.cpp: In function ‘constexpr T func(T) [with T = int]’: main.cpp:29:25: instantiated from here main.cpp:24:24: error: no matching function for call to ‘tfunc()’ main.cpp:24:24: note: candidate is: main.cpp:16:14: note: template<class T, T t> T

Can a string literal be subscripted in a constant expression?

泄露秘密 提交于 2019-11-27 22:50:32
This is valid, because a constexpr expression is allowed to take the value of "a glvalue of literal type that refers to a non-volatile object defined with constexpr, or that refers to a sub-object of such an object" (§5.19/2): constexpr char str[] = "hello, world"; constexpr char e = str[1]; However, it would seem that string literals do not fit this description: constexpr char e = "hello, world"[1]; // error: literal is not constexpr 2.14.5/8 describes the type of string literals: Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow