Consider a simple int Wrapper class with overloaded multiplication operator*= and operator*. For "old-style" operator-overloading, one can define operator* in terms of operator*=, and there are even libraries like Boost.Operators and its modern incarnation df.operators by @DanielFrey that reduce the boilerplate for you.

However, for compile-time computations using the new C++11 constexpr, this convenience disappears. A constexpr operator* cannot call operator*= because the latter modifies its (implicit) left argument. Furthermore, there is no overloading on constexpr, so adding an extra constexpr operator* to the existing operator* results in an overload resolution ambiguity.

My current approach is:

#include <iostream>

struct Wrap
{
    int value;    

    Wrap& operator*=(Wrap const& rhs) 
    { value *= rhs.value; return *this; }

    // need to comment this function because of overloading ambiguity with the constexpr version
    // friend Wrap operator*(Wrap const& lhs, Wrap const& rhs)
    // { return Wrap { lhs } *= rhs; }    

    friend constexpr Wrap operator*(Wrap const& lhs, Wrap const& rhs)
    { return { lhs.value * rhs.value }; }
};

constexpr Wrap factorial(int n)
{
    return n? factorial(n - 1) * Wrap { n } : Wrap { 1 };    
}

// want to be able to statically initialize these arrays
struct Hold
{
    static constexpr Wrap Int[] = { factorial(0), factorial(1), factorial(2), factorial(3) };
};

int main() 
{
    std::cout << Hold::Int[3].value << "\n"; // 6
    auto w = Wrap { 2 };
Edit
Report