I really can't find any use of it. My first idea was that I could use it to implement 'Design by Contract' without using macros like this:
struct S
{
S(constexpr int i) : S(i) { static_assert( i < 9, "i must be < 9" ); }
S(int i); //external defintion
char *pSomeMemory;
};
But this wouldn't compile. I thought we could also use it to reference same-variable without the need of additional memory to be created when we want to avoid the get/setters in order to make instances to one member from users to be read-only:
class S
{
private:
int _i;
public:
const int & constexpr i = _i;
};
But none of the above actually compiled. Can someone give me some insight why this keyword was being introduced?
Answer of " Can someone give me some insight why constexpr keyword was being introduced?"
Modern C++ supports two types of immutability.
1) const
2) constexpr.
constexper will be evaluated at the compile time. It is used to specify constness and allows placement of data in the memory where it might be corrupted.
Example 1:
Example 2:
Note: above source code are compiled on VS2015
The way I see it,
constexpr
is a way to bring together the two C++ languages - the one that runs at runtime and the one that runs at compile time. Compile time programming is usually called meta-programming.First there was C, with its macros. Macros were in fact little programs that were ran by the compiler. They had if statements (called
#ifdef
), variables (with#define
). There's even an entire scripting language that runs in compile time.When C++ came out, it had the C macros and nothing more. Then came the C++ templates. These introduced a different way of running compile-time code. The C++ meta-language was largely functional, allowing you to do loops with tail recursion, for example.
In C++ 11, they've decided that meta-programming can look better, so they've introduced
constexpr
. Now you can write C++ functions that are also meta-functions. In C++ 14 it gets better, because the restrictions on constexpr functions have been relaxed.Here is a summary of points made by Alex Allain in his "Constexpr - Generalized Constant Expressions in C++11," which details the usefulness of
constexpr
:constexpr
specifier, the value of the function or variable can be at compile time.constexpr
specifier is that it can replace macros with functionsconstexpr
will also benefit your template metaprogramming.Benefit to efficiency:
Other benefits:
Rules for
constexpr
functions:Rules for
constexpr
constructors:Citations
Allain, Alex, "Constexpr - Generalized Constant Expressions in C++11", Unspecified Date, "http://www.cprogramming.com/c++11/c++11-compile-time-processing-with-constexpr.html"
CPP, "Constexpr Specifier", 16 December 2014, http://en.cppreference.com/w/cpp/language/constexpr
EDIT: Sorry, It was my fault to make it seem like I was the author of these points, so I have corrected myself, changed various parts, and added citations to avoid plagiarism.
The goal of
constexpr
depends on the context:For objects it indicates that the object is immutable and shall be constructed at compile-time. Aside from moving operations to compile-time rather than doing them at run-time creating
constexpr
objects has the added advantage that they are initialize before any threads are created. As a result, their access never needs any synchronization. An example of declaring an object asconstexpr
would look like this:Obviously, for that to work,
args
need to be constant expressions.For functions it indicates that calling the function can result in a constant expression. Whether the result of
constexpr
function call results in a constant expression depends on the arguments and the definition of the function. The immediate implication is that the function has to beinline
(it will implicitly be made so). In addition, there are constraints on what can be done within such a function. For C++11 the function can have only one statement which, for non-constructors, has to be areturn
-statement. This restriction got relaxed in C++14. For example, the following is a definition of aconstexpr
function:When creating
constexpr
object of non-built-in types the respective types will need aconstexpr
constructor: the generated default constructor won't work. Obviously, aconstexpr
constructor will need to initialize all members. Aconstexpr
constructor could look like this:The created
constexpr
values can be used everywhere a constant expression is expected.