考虑一个简单的 int Wrapper
类,它具有重载的乘法 operator*=
和 operator*
。对于“老式”的运算符重载,可以用 operator*=
来定义 operator*
,甚至还有像 Boost.Operators 这样的库。及其现代化身df.operators @DanielFrey 为您减少了样板文件。
但是,对于使用新的 C++11 constexpr
进行编译时计算,这种便利就消失了。 constexpr operator*
不能调用 operator*=
因为后者修改了它的(隐式)左参数。此外,还有 no overloading on 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
}
Live output here .我的问题是:
operator*=
和operator*
中的乘法逻辑重复,而不是用表示
operator*
运算符*=- 因此,Boost.Operators 不再用于减少编写许多其他算术运算符的样板
问题:这是推荐的 C++11 方式,同时具有运行时 operator*=
和混合运行时/编译时 constexpr 运算符*
? C++14 是否将这里的任何内容更改为例如减少逻辑重复?
更新:@AndyProwl 的回答被认为是惯用的,但根据@DyP 的建议,在 C++11 中,可以减少逻辑重复,但代价是额外的任务和违反直觉的风格
// define operator*= in terms of operator*
Wrap& operator*=(Wrap const& rhs)
{ *this = *this * rhs; return *this; }
最佳答案
我找不到 C++11 的惯用解决方案(尽管作为一种变通方法,DyP's suggestion 对我来说似乎可以接受)。
然而,在 C++14 中,constexpr
does not imply const
(参见 C++14 标准草案 n3690 的附件 C.3.1),您可以简单地将 operator *=
和 operator *
定义为 constexpr
,并像往常一样根据前者定义后者:
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; }
};
这里是 live example ,上面的程序是在 Clang 上使用 -std=c++1y
编译的 - 不幸的是,GCC 似乎还没有实现这个规则。
关于c++ - 执行 constexpr 运算符重载的指南?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17744842/