【问题标题】:Overloading an operator through friend function and returning a type different from the rhs parameters通过友元函数重载运算符并返回与rhs参数不同的类型
【发布时间】:2013-08-22 14:07:16
【问题描述】:

我在此处附上代码并解释以下问题: 这是Bittop类:

#ifndef _Bitop_H
#define _Bitop_H

# include <iostream>

double num2fxp(double v, int bits=9, int intbits=5){
  return -0.5;
}

template<int bits = 8, int intbits = 6> 
class Bitop
{
  template<int rhsbits, int rhsintbits> friend class Bitop;

private:
  double value;   // data value

public:
  Bitop(const double& v=0): 
    value(num2fxp(v, bits, intbits))
  {}

  template<int rhsbits, int rhsintbits>
  const Bitop<bits, intbits>& operator = (const Bitop<rhsbits, rhsintbits>& v){
    value = num2fxp(v.value, bits, intbits); 
    return *this;
  }

  template<int rhsbits, int rhsintbits>  
  Bitop<bits, intbits>& operator += (const Bitop<rhsbits, rhsintbits>& v) {
    value = num2fxp(value+v.value, bits, intbits); 
    return *this; 
  }

  template<int lhsbits, int lhsintbits, int rhsbits, int rhsintbits>
  friend Bitop<lhsintbits+rhsintbits+2,  lhsintbits+rhsintbits+1> operator + (const     Bitop<lhsbits, lhsintbits>& x, const Bitop<rhsbits, rhsintbits>& y){ 
    return Bitop<lhsintbits+rhsintbits+2,  lhsintbits+rhsintbits+1>     (num2fxp(x.value+y.value));
  }

  friend std::ostream& operator<< (std::ostream & out, const Bitop& y){return out     <<  y.value ;}

  void Print(){
    std::cout << value<< "<"
      << bits << ","
      << intbits << ">";
  }
};
#endif

还有测试功能:

# include <iostream>
# include "Bitop.H"

using namespace std;

int main (int argc, char** argv) {

  Bitop<4,1> a = 0.8;
  Bitop<5,2> b(3.57);
  Bitop<7,3> c;

  c = b;

  cout << "See all attributes of c \n";
  c.Print();cout << "\n";

  c = 7.86;
  cout << "reassign c to a new value\n";
  c.Print();cout << "\n";

  cout << "set b = c \n";
  b = c;
  b.Print();cout<<"\n";

  cout << "set b+=a \n";
  b += a;
  b.Print();cout<<"\n";

  cout << "set b=c+a \n";
  b = c+a;
  b.Print();cout<<"\n";

  return 0;
}

我有一个模板类 Bitop。我想重载“+”以添加 2 个具有不同模板参数的对象并返回第三个对象,其参数不同于 rhs 和 lhs 对象,即我想做以下事情:

Bitop + Bitop 应该返回 Bitop。我将 Bitop 声明为它自己的友元类,这样我就可以访问 rhs 和 lhs 对象的私有成员。但是无论我是否调用“+”函数,都会出现编译错误(由于重新定义)。

我不清楚我在这里做错了什么。任何帮助表示赞赏。

请注意,我在代码中留下了几个函数和函数调用,以确保其他重载(例如 = 和 +=)正常工作。

【问题讨论】:

  • 与问题无关,但您应该真正尝试在您的+ 运算符中利用+=
  • 我认为问题在于不同的专业化最终定义了相同的模板朋友。尝试在课堂外定义operator+
  • 每个类都有一个injected-class-name;您可以使用它来摆脱像const Bitop&amp; operator = (...); 这样的显式模板参数。 IMO 它增加了可读性,特别是对于成员函数模板。
  • friend Bitop&lt;lhsintbits+rhsintbits+2, lhsintbits+rhsintbits+1&gt; operator+ 这不会为Bitop&lt;5,3&gt;+Bitop&lt;4,2&gt; 返回一个Bitop&lt;10,6&gt;,而是一个Bitop&lt;3+2+2, 3+2+1&gt;。错字?

标签: c++ templates operator-overloading friend-class


【解决方案1】:

这是一个显示相同问题的简化示例:

template<int i>
struct X {
    template<int a, int b>
    friend void foo(X<a>, X<b>) { }
};

int main()
{
    X<1> x1;
    X<4> x2; // error: redefinition of foo
}

每当X 的新特化被实例化时,foo 的定义就会插入到围绕模板类X 的作用域中。我希望很清楚错误来自哪里。

如果声明依赖于类的模板参数,情况会有所不同,例如:

template<int i>
struct X {
    template<int a, int b>
    friend void foo(X<a+i>, X<b+i>) { } // different definiton
                                        // for each specialization of X
};

解决办法是在类外定义友元函数:

template<int i>
struct X {
    template<int a, int b>
    friend void foo(X<a>, X<b>);

};

template<int a, int b>
void foo(X<a>, X<b>) { }

int main()
{
    X<1> x1;
    X<4> x2;
}

【讨论】:

  • 感谢您的解释。我按照答案进行操作!
【解决方案2】:

您实际上不需要将operator+ 定义为朋友:

template<int I>
class A
{
  double X;
  template<int> friend class A;
public:
  A(A const&) = default;

  A(double x)
    : X(x) {}

  template<int J>
  A(A<J> const&a)
    : X(a.X) {}

  template<int J>
  A<I+J> operator+ (A<J> const&a)
  { return A<I+J>(X+a.X); }
};

int main()
{
  A<0> a0(3);
  A<1> a1(4);
  auto ax = a0+a1;
}

此外,operator+(a,b) 返回的结果应该与operator=(a) 后跟operator+=(b) 得到的结果完全相同。

【讨论】:

    猜你喜欢
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    • 1970-01-01
    • 2015-06-03
    • 2022-01-13
    • 2011-03-19
    • 2017-07-26
    相关资源
    最近更新 更多