constexpr

Why does GCC think that the definition of a constexpr static data member must be marked constexpr?

巧了我就是萌 提交于 2019-11-29 16:12:22
问题 [C++14: 7.1.5/1]: The constexpr specifier shall be applied only to the definition of a variable or variable template, the declaration of a function or function template, or the declaration of a static data member of a literal type (3.9). If any declaration of a function, function template, or variable template has a constexpr specifier, then all its declarations shall contain the constexpr specifier. [..] Notice that the second sentence does not mention "a static data member" the way the

Why does the C++ compiler makes it possible to declare a function as constexpr, which can not be constexpr?

↘锁芯ラ 提交于 2019-11-29 15:02:35
Why does the C++ compiler makes it possible to declare a function as constexpr, which can not be constexpr? For example: http://melpon.org/wandbox/permlink/AGwniRNRbfmXfj8r #include <iostream> #include <functional> #include <numeric> #include <initializer_list> template<typename Functor, typename T, size_t N> T constexpr reduce(Functor f, T(&arr)[N]) { return std::accumulate(std::next(std::begin(arr)), std::end(arr), *(std::begin(arr)), f); } template<typename Functor, typename T> T constexpr reduce(Functor f, std::initializer_list<T> il) { return std::accumulate(std::next(il.begin()), il.end(

constexpr and std::cout working on function but not in lambda

有些话、适合烂在心里 提交于 2019-11-29 14:46:18
问题 Why constexpr does not work with std::cout , but works with printf ? #include <iostream> constexpr void f() { std::cout << ""; } //error constexpr void g() { printf(""); } //ok And why std::cout works with lambdas constexpr ? #include <iostream> int main () { auto h = []() constexpr { std::cout << ""; }; //ok } 回答1: Technically, it doesn't work with any of them. From [dcl.constexr]: For a constexpr function or constexpr constructor that is neither defaulted nor a template, if no argument

Defining constexpr static data members

若如初见. 提交于 2019-11-29 14:32:13
So, I'm aware that in C++ static members can be initialized inside the class if they are a const literal type like the following class test{ public: static constexpr int stc = 1; private: int a = 0; int b = 0; int c = 0; }; and the static constexpr variable stc can be used where the compiler can directly substitute the value of the member i.e int main () {int array[test::stc];} However, if used in a context where the value cannot be directly substituted by the compiler: int main() { const int &cs = test::stc; } then the compiler (clang) generates an error c++ -std=c++11 -pedantic t.cpp -o t

constexpr object with mutable member

房东的猫 提交于 2019-11-29 13:51:43
I came up with this class: class Point { public: int X, Y; mutable int Z; constexpr Point(int x, int y) :X (x), Y(y), Z(0) { } constexpr int GetX() const { // Z++; // Wont compile, but following expression is valid! return X+Z; } int GetY() const { Z++; return Y; } void FoolConst() const { Z++; } }; And here is usage: template<int S> void foo() { std::cout << S << std::endl; } int main() { constexpr Point pt(10, 20); pt.FoolConst(); char arr[pt.GetX()]; // Both compile, but GCC is using extended `new` foo<pt.GetX()>(); // GCC fails, VC compiles std::cout << sizeof(arr); // 10 (MSVC), 11 (GCC)

Getting around the reinterpret cast limitation with constexpr

旧街凉风 提交于 2019-11-29 13:21:58
In c++11, a constexpr expression cannot contain reinterpret casts. So for instance, if one wanted to manipulate the bits in a floating point number, say to find the mantissa of the number: constexpr unsigned int mantissa(float x) { return ((*(unsigned int*)&x << 9) >> 9); }; The above code would fail to be constexpr . In theory, I can't see how a reinterpret cast in this or similar cases can be any different from arithmetic operators, but the complier (and the standard) don't allow it. Is there any clever way of getting around this limitation? I can't see how a reinterpret cast in this or

Difference between string literal and constexpr array of char

天大地大妈咪最大 提交于 2019-11-29 13:15:51
I have been wondering if there is any difference between what is being pointed by ptrToArray and ptrToLiteral in the following example: constexpr char constExprArray[] = "hello"; const char* ptrToArray = constExprArray; const char* ptrToLiteral = "hello"; Is my understanding that constExprArray and the two "hello" literals are all compile time constant lvalues correct? If so, is there any difference in how they are stored in the executable file, or is it purely compiler implementation or platform specific? Are they treated differently at runtime behind the scenes? Anything else to know about?

constexpr array and std::initializer_list

北城余情 提交于 2019-11-29 11:27:36
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): _size(values.size()), _data(values.begin()) {} constexpr auto operator[](std::size_t n) -> T { return

C++11 constexpr function compiler error with ternary conditional operator (?:)

試著忘記壹切 提交于 2019-11-29 11:21:43
What is wrong with this piece of code? #include <iostream> template<unsigned int N, unsigned int P=0> constexpr unsigned int Log2() { return (N <= 1) ? P : Log2<N/2,P+1>(); } int main() { std::cout << "Log2(8) = " << Log2<8>() << std::endl; return 0; } When compiling with gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) , I get the following error: log2.cpp: In function ‘constexpr unsigned int Log2() [with unsigned int N = 0u, unsigned int P = 1023u]’: log2.cpp:5:38: error: template instantiation depth exceeds maximum of 1024 (use -ftemplate-depth= to increase the maximum) instantiating

Simple variadic template function can't instantinate

谁都会走 提交于 2019-11-29 11:14:14
I'm aware that sizeof...(Args...) yields the number of types in a C++0x packed template argument list, but I wanted to implement it in terms of other features for demonstation purposes, but it won't compile. // This is not a solution -- overload ambiguity. // template <typename... Args> size_t num_args (); // Line 7 // template <> constexpr size_t num_args () { return 0; } template <typename H, typename... T> constexpr size_t num_args () // Line 16 { return 1 + num_args <T...> (); // *HERE* } int main () { std :: cout << num_args <int, int, int> (); } This errors at *HERE* with No matching