constexpr

constexpr Function

#include <iostream>
#include <utility>
#include <chrono>

class Timer {
public:
    inline void start() {
        start_ = std::chrono::system_clock::now();
    }

    inline void end() {
        end_ = std::chrono::system_clock::now();
    }

    inline void out() {
        std::chrono::duration<double> d = end_ - start_;
        std::cout << "Time cost: " << d.count() << "\n";
    }
private:
    std::chrono::time_point<std::chrono::system_clock> start_;
    std::chrono::time_point<std::chrono::system_clock> end_;
};

constexpr long fib(long n) {
    return (n < 2) ? 1 : fib(n-1) + fib(n-2);
}

int main() {
    Timer timer;
    long n = 40;

    timer.start();
    int r1 = fib(n);
    timer.end();
    timer.out();

    timer.start();
    constexpr long r2 = fib(40);
    timer.end();
    timer.out();

    return 0;
}

output:

$ g++ -std=c++14 -g -O3 a.cpp
$ ./a.out
Time cost: 0.268229
Time cost: 8e-06

Compare to Metaprogramming

#include <iostream>
#include <utility>
#include "timer.h"

template <long N>
struct Fib {
    static long const v = Fib<N-1>::v + Fib<N-2>::v;
};

template <>
struct Fib<0> {
    static long const v = 1;
};

template <>
struct Fib<1> {
    static long const v = 1;
};

constexpr long fib(long n)
{
    return (n < 2) ? 1 : fib(n-1) + fib(n-2);
}

int main() {

    Timer timer;

    timer.start();
    constexpr long r1 = Fib<40>::v;
    timer.end();
    timer.out();

    timer.start();
    constexpr long r2 = fib(40);
    timer.end();
    timer.out();

    return 0;
}

output:

g++ -std=c++14 -g -O3 a.cpp
$ ./a.out
Time cost: 9.7e-06
Time cost: 9.2e-06

After C++14, constexpr functions can

  • invoke other constexpr functions.

  • have variables with a constant expression.

  • include conditional expressions or loops.

  • be implicit inline.

  • not have static or thread_local data.