Tem*_*Rex 26 c++ operator-overloading constexpr c++11 c++14
考虑一个简单的INT Wrapper与重载乘法类operator*=和operator*.对于"旧式"运算符重载,可以定义operator*,operator*=甚至还有像Boost.Operators这样的库以及@DanielFrey的现代化版本操作符,它们可以为您减少样板.
但是,对于使用新C++ 11的编译时计算constexpr,这种便利性消失了.A constexpr 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
}
Run Code Online (Sandbox Code Playgroud)
现场输出.我的问题是:
operator*=和operator*,而不是operator*在形式表示operator*=问题:这是推荐的C++ 11兼具运行时operator*=和混合运行时/编译时的方法constexpr operator*吗?C++ 14是否会改变任何内容以减少逻辑重复?
更新:@AndyProwl的答案被认为是惯用的,但根据@DyP的建议,在C++ 11中,可以减少逻辑重复,但会牺牲额外的赋值和反直觉的风格
// define operator*= in terms of operator*
Wrap& operator*=(Wrap const& rhs)
{ *this = *this * rhs; return *this; }
Run Code Online (Sandbox Code Playgroud)
And*_*owl 20
我无法找到C++ 11的惯用解决方案(虽然作为一种解决方法,DyP的建议似乎对我来说是可接受的).
然而,在C++ 14中,constexpr并不暗示const(参见C++ 14标准草案n3690的附录C.3.1),您可以像往常一样简单地定义两者operator *=和operator *as 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; }
};
Run Code Online (Sandbox Code Playgroud)
这是一个实例,上面的程序是用-std=c++1yClang 编译的- 不幸的是,GCC似乎还没有实现这个规则.
| 归档时间: |
|
| 查看次数: |
6480 次 |
| 最近记录: |