Руководство по выполнению операторской перегрузки constexpr?

Рассмотрим простой intWrapper класс с перегруженным умножениемoperator*= а такжеoperator*, За "Старый стиль" перегрузка оператора, можно определитьoperator* с точки зренияoperator*=и есть даже библиотеки вродеBoost.Operators и его современное воплощениеdf.operators @DanielFrey, которые уменьшают шаблон для вас.

Тем не менее, для вычислений во время компиляции с использованием нового C ++ 11constexprэто удобство исчезает.constexpr operator* не могу позвонитьoperator*= потому что последний изменяет свой (неявный) левый аргумент. Кроме того, естьнет перегрузки на constexprтак что добавление дополнительныхconstexpr operator* к существующемуoperator* приводит к неоднозначности разрешения перегрузки.

Мой текущий подход:

#include 

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 };
    w *= Wrap { 3 };
    std::cout < w.value < "\n"; // 6
}

Ответы на вопрос(1)

Ваш ответ на вопрос