constexpr

Is constexpr a “hint” (like inline) or “a binding request” to the compiler?

本秂侑毒 提交于 2019-11-27 22:47:39
Is constexpr an indicator for the compiler or does it mandate a behaviour ? The example at hand is the following : template<typename T> std::size_t constexpr getID() { return typeid(T).hash_code(); } hash_code is a runtime constant, yet this snippet would compile even though a compile time evaluation is requested with constexpr . Only after the return value is used where a compile time constant is expected, would we get noticed that this is not usable as a constexpr function . So is constexpr a "hint" (much like the inline keyword) or "a binding request" to the compiler ? From the C++11 Wiki

Can an exception be thrown from the ternary operator?

人走茶凉 提交于 2019-11-27 22:45:40
Sometimes it is convenient or even necessary to have a function which just one statement (it is necessary when returning a constexpr ). If a condition needs to be checked and only one statement is allowed, the conditional operator is the only option. In case of an error it would be nice to throw an exception from the conditional operator, e.g.: template <typename It> typename std::iterator_traits<It>::reference access(It it, It end) { return it == end? throw std::runtime_error("no element"): *it; } The above function doesn't compile, however, when used for example as ( live example ): std:

Forcing a constant expression to be evaluated during compile-time?

我只是一个虾纸丫 提交于 2019-11-27 22:23:18
A few days ago I asked by which criteria the compiler decides whether or not, to compute a constexpr function during compile time. When does a constexpr function get evaluated at compile time? As it turns out, a constexpr is only evaluated during compile-time, if all parameters are constant expressions and the variable you are assigning it to is are constant expression as well. template<typename base_t, typename expo_t> constexpr base_t POW(base_t base, expo_t expo) { return (expo != 0 )? base * POW(base, expo -1) : 1; } template<typename T> void foobar(T val) { std::cout << val << std::endl;

Why does constexpr static member (of type class) require a definition?

假如想象 提交于 2019-11-27 21:31:55
==> See the full snippet code and compilation on coliru . I have a LiteralType class filling constexpr requirements : struct MyString { constexpr MyString(char const* p, int s) : ptr(p), sz(s) {} constexpr char const* data() const { return ptr; } constexpr int size() const { return sz; } char const *ptr = 0; int const sz = 0; }; I use it as a constexpr static member variable: struct Foo { int size() { return str_.size(); } constexpr static MyString str_{"ABC",3}; }; int main() { Foo foo; return ! foo.size(); } But the linker says: (Clang-3.5 and GCC-4.9) undefined reference to `Foo::str_' I

constexpr function parameters as template arguments

≯℡__Kan透↙ 提交于 2019-11-27 21:12:21
I am playing around with some toy code using c++11 to figure out a bit more about how things work. During this I came across the following issue that simplifies down to: template <int x, int y> class add { public: static constexpr int ret = x + y; }; constexpr int addFunc(const int x, const int y) { return add<x,y>::ret; } int main() { const int x = 1; const int y = 2; cout << add<x,y>::ret << endl; // Works cout << addFunc(1,2) << endl; // Compiler error return 0; } I'm using GCC 4.8.1 and the output is: 'x' is not a constant expression in template argument for type 'int' 'y' is not a

constexpr global constants in a header file and odr

我与影子孤独终老i 提交于 2019-11-27 20:32:25
问题 Unfortunately, I am somewhat confused about constexpr , global constants declared in header files, and the odr. In short: Can we conclude from here https://isocpp.org/files/papers/n4147.pdf that constexpr MyClass const MyClassObj () { return MyClass {}; } constexpr char const * Hello () { return "Hello"; } is preferable over constexpr MyClass const kMyClassObj = MyClass {}; constexpr char const * kHello = "Hello"; for defining globals in a header file if I want to "just use" those globally

Can I obtain C++ type names in a constexpr way?

我怕爱的太早我们不能终老 提交于 2019-11-27 20:28:05
I would like to use the name of a type at compile time. For example, suppose I've written: constexpr size_t my_strlen(const char* s) { const char* cp = s; while(*cp != '\0') { cp++; }; return cp - s; } and now I want to have: template <typename T> constexpr auto type_name_length = my_strlen(typeid(T).name()); But alas, typeid(T).name() is just const char* , not constexpr... is there some other, constexpr way to get a type's name? Well, you could, sort of, but probably not quite portable: struct string_view { char const* data; std::size_t size; }; inline std::ostream& operator<<(std::ostream& o

constexpr const vs constexpr variables? [duplicate]

我与影子孤独终老i 提交于 2019-11-27 20:00:52
This question already has an answer here: Difference between `constexpr` and `const` 8 answers It seems obvious that constexpr implies const and thus it is common to see: constexpr int foo = 42; // no const here However if you write: constexpr char *const str = "foo"; Then GCC will spawn "warning: deprecated conversion from string constant to ‘char*’" if -Wwrite-string flag is passed. Writing: constexpr const char *const str = "foo"; solves the issue. So are constexpr const and constexpr really the same? The issue is that in a variable declaration, constexpr always applies the const -ness to

Why doesn't an if constexpr make this core constant expression error disappear?

吃可爱长大的小学妹 提交于 2019-11-27 19:40:26
In reference to this question . The core constant expression that is used to initialize the constexpr variable y is ill-formed. So much is a given. But if I try to turn the if into an if constexpr : template <typename T> void foo() { constexpr int x = -1; if constexpr (x >= 0){ constexpr int y = 1 << x; } } int main(){ foo<int>(); } The error persists. With GCC 7.2 still giving: error: right operand of shift expression '(1 << -1)' is negative [-fpermissive] But I thought that the semantic check should be left unpreformed on a discarded branch. Making an indirection via a constexpr lambda does

static_assert on initializer_list::size()

北城余情 提交于 2019-11-27 18:45:59
Why is std::initializer_list<_E>::size not allowable in a static_assert, even though it's declared as a constexpr in my libstdc++ (v. 4.6)? For example, the following code: template<class T, int Length> class Point { public: Point(std::initializer_list<T> init) { static_assert(init.size() == Length, "Wrong number of dimensions"); } }; int main() { Point<int, 3> q({1,2,3}); return 0; } gives the following error: test.C: In constructor ‘Point<T, Length>::Point(std::initializer_list<_Tp>) [with T = int, int Length = 3]’: test.C:60:26: instantiated from here test.C:54:7: error: non-constant