Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
复杂的运算符重载和模板 这是C++中定点运算的一个极其疯狂的实现。请不要评论这一切是多么糟糕和毫无意义_C++_Templates_Operator Overloading_Friend - Fatal编程技术网

复杂的运算符重载和模板 这是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){
如果(N1std::难道
x
确实受到保护,而且显然您试图将运算符+=声明为友元。但是我认为您的友元声明与您实现的运算符不匹配。我不相信模板的不同专门化可以访问彼此
受保护的
变量,除非专门化是朋友。请看,
x
确实受到保护,而且显然您正试图将运算符+=声明为朋友。但我认为您的朋友声明与您实现的运算符不匹配。我不相信模板的不同专门化可以访问彼此受保护的
变量,除非特殊蜥蜴是朋友,看到了吗