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: 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;
}



//
// 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;
}









// 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