首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >操作者-超载指南?

操作者-超载指南?
EN

Stack Overflow用户
提问于 2013-07-19 11:19:45
回答 1查看 11.4K关注 0票数 28

考虑一个简单的int Wrapper类,它包含重载的乘法、operator*=operator*。对于“旧式”操作符重载,我们可以用operator*=来定义operator*=,甚至还有像Boost.Operators这样的库以及@DanielFrey的现代版本df.operators,它们可以为您减少样板。

然而,对于使用新的C++11 constexpr进行编译时计算,这种方便就消失了。constexpr operator*不能调用operator*=,因为后者修改其(隐式)左参数。此外,还有无超载现象,因此在现有的operator*中添加一个额外的constexpr operator*会导致重载解决的模糊性。

我目前的做法是:

代码语言:javascript
复制
#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*=和混合运行时/编译时constexpr operator*的C++11方式吗?C++14是否改变了这里的任何内容,例如减少逻辑复制?

UPDATE:@AndyProwl的回答被认为是惯用的,但按照@DyP的建议,在C++11 1中,可以减少逻辑重复,而牺牲额外的赋值和违反直觉的风格。

代码语言:javascript
复制
    // define operator*= in terms of operator*
    Wrap& operator*=(Wrap const& rhs) 
    { *this = *this * rhs; return *this; }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-19 12:28:27

我无法为C++11找到一个惯用的解决方案(尽管作为一种解决办法,DyP建议在我看来是可以接受的)。

然而,在C++14中,const (见C++14标准草案n3690附件C.3.1 )可以简单地将operator *=operator *定义为constexpr,而后者定义为前者,就像往常一样:

代码语言:javascript
复制
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; }    
};

这里是一个实例化,上面的程序是用-std=c++1y编译的--不幸的是,GCC似乎还没有实现这个规则。

票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17744842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档