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 constant expression in template argument for type 'int'
What exactly is the difference between the two ways I am trying to calculate add::ret
? Both of these values should be available at compile time.
We allow annotating a function parameter with constexpr with the same meaning as a variable declaration: must be initialized with a constant expression. We add a new keyword, maybe_constexpr , that deduces whether the parameter is known at compile time.
A const int var can be dynamically set to a value at runtime and once it is set to that value, it can no longer be changed. A constexpr int var cannot be dynamically set at runtime, but rather, at compile time. And once it is set to that value, it can no longer be changed.
Understanding constexpr Specifier in C++ constexpr is a feature added in C++ 11. The main idea is a performance improvement of programs by doing computations at compile time rather than run time.
Yes. I believe putting such const ness is always a good practice wherever you can. For example in your class if a given method is not modifying any member then you always tend to put a const keyword in the end.
If your purpose is just to shorten code a bit, in C++14 you can create variable template:
template <int x, int y> constexpr int addVar = x + y; cout << addVar<5, 6> << endl; // Works with clang 3.5, fails on GCC 4.9.1
GCC 5 will also support this.
You tell the compiler, that addFunc
would be a constexpr. But it depents on parameters, that are not constexpr itself, so the compiler already chokes on that. Marking them const only means you are not going to modify them in the function body, and the specific calls you make to the function are not considered at this point.
There is a way you can make the compiler understand you are only going to pass compile time constants to addFunc
: Make the parameters a template parameters itself:
template <int x, int y> constexpr int addFunc() { return add<x,y>::ret; }
Then call as
cout << addFunc<1,2>() << endl;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With