复杂的运算符重载和模板 这是C++中定点运算的一个极其疯狂的实现。请不要评论这一切是多么糟糕和毫无意义
如您所见,小数部分复杂的运算符重载和模板 这是C++中定点运算的一个极其疯狂的实现。请不要评论这一切是多么糟糕和毫无意义,c++,templates,operator-overloading,friend,C++,Templates,Operator Overloading,Friend,如您所见,小数部分N有一个基类型T和一个二进制位数。需要将FixedNum+FixedNum计算为FixedNum。下面是我如何尝试实现它的。但是,GCC表示,最后一行中对x的赋值是错误的,因为x受到保护。怎么了 #define MAX(a,b) (((a)>(b))?(a):(b)) template <typename T, int N> class FixedNum { public: template <int N2>
N
有一个基类型T
和一个二进制位数。需要将FixedNum+FixedNum
计算为FixedNum。
下面是我如何尝试实现它的。但是,GCC表示,最后一行中对x
的赋值是错误的,因为x
受到保护。怎么了
#define MAX(a,b) (((a)>(b))?(a):(b))
template <typename T, int N>
class FixedNum
{
public:
template <int N2>
friend FixedNum& operator+(const FixedNum& f, const FixedNum& g);
template <int N2>
friend FixedNum& operator+=(const FixedNum& f, const FixedNum& g);
FixedNum(T x): x (x) {}
T num() const { return x; }
int point() const { return N; }
protected:
T x;
};
template <typename T, int N, int N2>
FixedNum<T, MAX(N, N2)>& operator+(const FixedNum<T, N>& f, const FixedNum<T, N2>& g)
{
return FixedNum<T, N>(f) += g;
}
template <typename T, int N, int N2>
FixedNum<T, MAX(N, N2)>& operator+=(const FixedNum<T, N>& f, const FixedNum<T, N2>& g)
{
#if N2 <= N
f.x += g.x << (N-N2);
#else
f.x <<= (N2-N);
f.x += g.x;
#endif
}
定义最大值(a,b)((a)>(b))?(a):(b))
样板
类固定数
{
公众:
样板
friend FixedNum和operator+(const FixedNum和f,const FixedNum和g);
样板
friend FixedNum&operator+=(const FixedNum&f,const FixedNum&g);
FixedNum(tx):x(x){}
T num()常量{return x;}
int point()常量{return N;}
受保护的:
tx;
};
样板
FixedNum和运算符+(常量FixedNum和f、常量FixedNum和g)
{
返回FixedNum(f)+=g;
}
样板
FixedNum和运算符+=(常数FixedNum和f,常数FixedNum和g)
{
#如果N2您必须使用
bool
选择器模板并将其专门化为N2您必须使用bool
选择器模板并将其专门化为N2模板类类型的每个实例化都是不同的类。
请记住,这些类实际上具有不同的名称,并且与继承无关
FixedNum
是一个唯一的名称,它将不同于类类型FixedNum
因此,它们无法访问彼此的受保护成员
您必须将所有“相似”的模板类都标记为好友,如下所示:
template<typename T, int N> friend class FixedNum;
模板好友类FixedNum;
除此之外,使用预处理器#if在那里不会像您希望的那样工作。
预处理器与它的名称非常相似,它在编译器开始处理所有代码之前进行处理。因此它只计算宏值和处理器定义。模板类类型的每个实例化都是一个不同的类。
请记住,这些类实际上具有不同的名称,并且与继承无关
FixedNum
是一个唯一的名称,它将不同于类类型FixedNum
因此,它们无法访问彼此的受保护成员
您必须将所有“相似”的模板类都标记为好友,如下所示:
template<typename T, int N> friend class FixedNum;
模板好友类FixedNum;
除此之外,使用预处理器#if在那里不会像您希望的那样工作。
预处理器与它的名称非常相似,它在编译器开始处理所有代码之前进行处理。因此它只计算宏值和处理器定义。可能是这样的:
#include <iostream>
template <typename T, int N>
class FixedNum
{
public:
FixedNum(T x): x (x) {}
T num() const { return x; }
int point() const { return N; }
// A += with a FixedNum with a different N is pointless.
FixedNum& operator+=(const FixedNum& g) {
x += g.x;
return *this;
}
protected:
T x;
};
// A helper class to provide the result type and operation.
template <typename T, int N1, int N2>
struct FixedNumAdd
{
typedef FixedNum<T, (N1 < N2) ? N2 : N1> result_type;
static result_type apply(const FixedNum<T, N1>& f, const FixedNum<T, N2>& g) {
if(N1 < N2) {
T x = f.num();
for(int i = N1; i < N2; ++i) x *= 10;
return result_type(x) += g.num();
}
else {
T x = g.num();
for(int i = N2; i < N1; ++i) x *= 10;
return result_type(x) += f.num();
}
}
};
template <typename T, int N1, int N2>
inline typename::FixedNumAdd<T, N1, N2>::result_type
operator + (const FixedNum<T, N1>& f, const FixedNum<T, N2>& g)
{
return FixedNumAdd<T, N1, N2>::apply(f, g);
}
int main() {
FixedNumAdd<int, 1, 2>::result_type result
= FixedNum<int, 1>(11)
+ FixedNum<int, 2>(13);
std::cout << double(result.num()) / 100 << std::endl;
return 0;
}
#包括
样板
类固定数
{
公众:
FixedNum(tx):x(x){}
T num()常量{return x;}
int point()常量{return N;}
//具有不同N的FixedNum的A+=是没有意义的。
FixedNum和运算符+=(常量FixedNum和g){
x+=g.x;
归还*这个;
}
受保护的:
tx;
};
//提供结果类型和操作的帮助器类。
样板
结构FixedNumAdd
{
typedef FixedNum result_type;
静态结果类型应用(常数固定数和f、常数固定数和g){
如果(N1
#include <iostream>
template <typename T, int N>
class FixedNum
{
public:
FixedNum(T x): x (x) {}
T num() const { return x; }
int point() const { return N; }
// A += with a FixedNum with a different N is pointless.
FixedNum& operator+=(const FixedNum& g) {
x += g.x;
return *this;
}
protected:
T x;
};
// A helper class to provide the result type and operation.
template <typename T, int N1, int N2>
struct FixedNumAdd
{
typedef FixedNum<T, (N1 < N2) ? N2 : N1> result_type;
static result_type apply(const FixedNum<T, N1>& f, const FixedNum<T, N2>& g) {
if(N1 < N2) {
T x = f.num();
for(int i = N1; i < N2; ++i) x *= 10;
return result_type(x) += g.num();
}
else {
T x = g.num();
for(int i = N2; i < N1; ++i) x *= 10;
return result_type(x) += f.num();
}
}
};
template <typename T, int N1, int N2>
inline typename::FixedNumAdd<T, N1, N2>::result_type
operator + (const FixedNum<T, N1>& f, const FixedNum<T, N2>& g)
{
return FixedNumAdd<T, N1, N2>::apply(f, g);
}
int main() {
FixedNumAdd<int, 1, 2>::result_type result
= FixedNum<int, 1>(11)
+ FixedNum<int, 2>(13);
std::cout << double(result.num()) / 100 << std::endl;
return 0;
}
#包括
样板
类固定数
{
公众:
FixedNum(tx):x(x){}
T num()常量{return x;}
int point()常量{return N;}
//具有不同N的FixedNum的A+=是没有意义的。
FixedNum和运算符+=(常量FixedNum和g){
x+=g.x;
归还*这个;
}
受保护的:
tx;
};
//提供结果类型和操作的帮助器类。
样板
结构FixedNumAdd
{
typedef FixedNum result_type;
静态结果类型应用(常数固定数和f、常数固定数和g){
如果(N1 std::难道x
确实受到保护,而且显然您试图将运算符+=声明为友元。但是我认为您的友元声明与您实现的运算符不匹配。我不相信模板的不同专门化可以访问彼此受保护的变量,除非专门化是朋友。请看,x
确实受到保护,而且显然您正试图将运算符+=声明为朋友。但我认为您的朋友声明与您实现的运算符不匹配。我不相信模板的不同专门化可以访问彼此受保护的变量,除非特殊蜥蜴是朋友,看到了吗