0

我在此处附上代码并解释以下问题: 这是 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<5,3> + Bitop<4,2> 应该返回 Bitop<10,6>。我将 Bitop 声明为它自己的友元类,这样我就可以访问 rhs 和 lhs 对象的私有成员。但是无论我是否调用“+”函数,我都会收到编译错误(由于重新定义)。

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

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

4

2 回答 2

0

你真的不需要定义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;
}

而且, by 返回的结果operator+(a,b)应该真的和 follow by 得到的结果是一样operator=(a)operator+=(b)

于 2013-08-22T14:26:45.610 回答
0

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

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;
}
于 2013-08-22T14:30:29.093 回答