考虑一个简单的 intWrapper
类,它具有重载的乘法operator*=
和operator*
. 对于“旧式”运算符重载,可以根据 定义operator*
,operator*=
甚至还有像Boost.Operators这样的库以及@DanielFrey的现代化身df.operators可以为您减少样板文件。
然而,对于使用新的 C++11 的编译时计算constexpr
,这种便利就消失了。Aconstexpr operator*
不能调用operator*=
,因为后者修改了它的(隐式)左参数。此外,在 constexpr 上没有重载constexpr operator*
,因此在现有结果中添加额外内容会operator*
导致重载决议模糊。
我目前的做法是:
#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 };
w *= Wrap { 3 };
std::cout << w.value << "\n"; // 6
}
现场输出在这里。我的问题是:
- 和 中的乘法逻辑的重复
operator*=
,operator*
而不是operator*
表示为operator*=
- 因此,Boost.Operators 不再用于减少编写许多其他算术运算符的样板文件
问题:这是推荐的具有运行时operator*=
和混合运行时/编译时的 C++11 方式constexpr operator*
吗?C++14 是否改变了这里的任何东西以减少逻辑重复?
更新:@AndyProwl 的答案被认为是惯用的,但根据@DyP 的建议,在 C++11 中,可以通过额外的赋值和反直觉的风格来减少逻辑重复
// define operator*= in terms of operator*
Wrap& operator*=(Wrap const& rhs)
{ *this = *this * rhs; return *this; }