consider simple int wrapper class overloaded multiplication operator*= , operator*. "old-style" operator-overloading, 1 can define operator* in terms of operator*=, , there libraries boost.operators , modern incarnation df.operators @danielfrey reduce boilerplate you.
however, compile-time computations using new c++11 constexpr, convenience disappears. constexpr operator* cannot call operator*= because latter modifies (implicit) left argument. furthermore, there no overloading on constexpr, adding constexpr operator* existing operator* results in overload resolution ambiguity.
my current approach is:
#include <iostream> struct wrap { int value; wrap& operator*=(wrap const& rhs) { value *= rhs.value; return *this; } // need comment function because of overloading ambiguity 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 able 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 } live output here. problems are:
- duplication of multiplication logic in both
operator*=,operator*, instead ofoperator*being expressed in terms ofoperator*= - hence, boost.operators no longer works reduce boilerplate writing many other arithmetic operators
question: recommended c++11 way of having both run-time operator*= , mixed run-time/compile-time constexpr operator*? c++14 change here e.g. reduce logic duplication?
update: answer @andyprowl accepted idiomatic per suggestion of @dyp, in c++11 1 could reduce logic duplication @ expense of assignment , counter-intuitive style
// define operator*= in terms of operator* wrap& operator*=(wrap const& rhs) { *this = *this * rhs; return *this; }
i not find idiomatic solution c++11 (although workaround, dyp's suggestion seems acceptable me).
in c++14 however, constexpr not imply const (see annex c.3.1 of c++14 standard draft n3690), define both operator *= , operator * constexpr, , define latter in terms of former, usual:
struct wrap { int value; constexpr wrap& operator *= (wrap const& rhs) { value *= rhs.value; return *this; } friend constexpr wrap operator * (wrap const& lhs, wrap const& rhs) { return wrap(lhs) *= rhs; } }; here live example, above program being compiled -std=c++1y on clang - unfortunately, gcc not seem implement rule yet.
Comments
Post a Comment