Since C+11 we have generalized constants, i.e. constexpr



Constexpr variable

 - immediately constructed or assigned
 - must contain only literal values, constexpr variables and functions
 - the constructor used must be constexpr constructor

Constexpr function
 - must not be virtual
 - return type must be LiteralType
 - parameters must be literal type
 - body must be either deleted or defaulted or contain only the following:
      null statements
      static_assert declarations
      typedef declarations and alias declarations that do not define classes or enumerations
      using declarations
      using directives
      C++11: exactly one return statement
      C++14: -

Constexpr constructor
 - parameters must be literal type
 - must have no virtual base classes
 - either deleted or defaulted or contain only the following:
      ...as above...

 - the constructor must not have a function-try block
 - base class and every non-static member must be initialized
 - every implicit conversion involved must be a constant expression


Constexpr functions can be called with all constexpr parameter values
  - the return value can be assigned to a constexpr variable
or non constexpr values
  - the return value can be assigned to non-constexpr variable



//
// C++11:
// From Scott Meyers: Effective Modern C++

constexpr int pow( int base, int exp) noexcept
{
    return  exp == 0 ? 1 : base * pow(base, exp-1) ;
}


// C++14
constexpr int pow( int base, int exp) noexcept
{
    auto result = 1;

    for (int i = 0; i < exp; ++i) result *= base;

    return result;
}



//
//  C++11: constexpr must be a single return statement
//  C++14: should be fine
//

#include <iostream>

constexpr int strlen(const char *s)
{
    const char *p = s;
    while ( '\0' != *p )  ++p;
    return p-s;
}

// C++11:
// constexpr.cpp: In function ‘constexpr int strlen(const char*)’:
// constexpr.cpp:9:1: error: body of constexpr function ‘constexpr int strlen(const char*)’
// not a return-statement

int main()
{
    std::cout << strlen("Hello") << std::endl;
    return 0;
}






// from http://en.cppreference.com/w/cpp/language/constexpr

#include <iostream>
#include <stdexcept>

// literal class
class conststr {
    const char * p;
    std::size_t sz;
 public:
    template<std::size_t N>
    constexpr conststr(const char(&a)[N]) : p(a), sz(N-1) {}
    // constexpr functions signal errors by throwing exceptions from operator ?:
    constexpr char operator[](std::size_t n) {
        return n < sz ? p[n] : throw std::out_of_range("");
    }
    constexpr std::size_t size() { return sz; }
};
constexpr std::size_t countlower(conststr s, std::size_t n = 0,
                                             std::size_t c = 0) {
    return n == s.size() ? c :
           s[n] >= 'a' && s[n] <= 'z' ? countlower(s, n+1, c+1) :
                                        countlower(s, n+1, c);
}

template<int n> struct constN {
    constN() { std::cout << n << '\n'; }
};

int main()
{

    std::cout << "Number of lowercase letters in \"Hello, world!\" is ";
    constN<countlower("Hello, world!")> out2; // implicitly converted to conststr
}

// Number of lowercase letters in "Hello, world!" is 9




// literal type



class Point
{
public:
    constexpr Point(double xVal = 0, double yVal = 0) noexcept
                : x(xVal), y(yVal)  {}

    // in C++11 constexpr => const, in C++14 is not 
    constexpr double xValue() const noexcept { return x; }
    constexpr double yValue() const noexcept { return y; }

    // can be constexpr in C++14
    constexpr void setX(double newX) noexcept { x = newX; }
    constexpr void setY(double newY) noexcept { y = newY; }
private:
    double x, y;
};



constexpr Point p1(42.0, -33.33); // fine, "runs" constexpr
                                  // ctor during compilation
constexpr Point p2(25.0, 33.3);   // also fine



constexpr Point midpoint(const Point& p1, const Point& p2) noexcept
{
    return { (p1.xValue() + p2.xValue()) / 2,   // call constexpr
             (p1.yValue() + p2.yValue()) / 2 }; // member funcs
}
constexpr auto mid = midpoint(p1, p2); // init constexpr
                                       // object w/result of
                                       // constexpr function



// in C++14, where setX and setY are constexpr:
// return reflection of p with respect to the origin (C++14)
constexpr Point reflection(const Point& p) noexcept
{
    Point result;             // create non-const Point
    result.setX(-p.xValue()); // set its x and y values
    result.setY(-p.yValue());
    return result;            // return copy of it
}


constexpr auto midReflected = reflection(mid);




Template metaprograms only emulates floating point vales.