如何重载从 C++ 中的模板继承的类的赋值运算符

How to overload the assignment operator for a class that inherits from a template in c++

提问人:Comedian6969 提问时间:5/25/2019 最后编辑:Comedian6969 更新时间:5/25/2019 访问量:96

问:

我标记了一个给定的实用程序模板类。我不得不使用这些模板类声明 2 个新结构,如下所示。

标签.h

#ifndef TAGGED_H
#define TAGGED_H

#include <iostream>


template<typename T, typename TAG>
class tagged
{
private:
    T _value;

public:
    tagged() : _value() { }

    explicit tagged(const T& value) : _value(value) { }    

    // https://isocpp.org/wiki/faq/templates#template-friends
    friend T& value(tagged<T, TAG>& st)
    {
        return st._value;
    }

    friend const T& value(const tagged<T, TAG>& st)
    {
        return st._value;
    }
};

template<typename T>
struct equality
{
    friend bool operator ==(const T& x, const T& y)
    {
        return value(x) == value(y);
    }

    friend bool operator !=(const T& x, const T& y)
    {
        return value(x) != value(y);
    }
};

template<typename T>
struct ordered : equality<T>
{
    friend bool operator <(const T& x, const T& y)
    {
        return value(x) < value(y);
    }

    friend bool operator <=(const T& x, const T& y)
    {
        return value(x) <= value(y);
    }

    friend bool operator >(const T& x, const T& y)
    {
        return value(x) > value(y);
    }

    friend bool operator >=(const T& x, const T& y)
    {
        return value(x) >= value(y);
    }
};

这是我按照赋值给出的规则声明的两个结构。 基元.h

//Time
struct __declspec(empty_bases)Time : tagged<uint64_t, Time>, ordered<Time>, show_value<Time, int>{ using tagged::tagged; };


//Duration
struct __declspec(empty_bases)Duration : tagged<uint64_t, Duration>, ordered<Duration>, show_value<Duration, int> { using tagged::tagged; };

我成功地编写了所有其他运算符,例如 + 和 - ,但我似乎无法解决如何重载 += 和 -= 我不允许更改 tagged.h 中的对象,我知道赋值运算符只能是成员函数。由于模板的工作方式,我尝试将“const Time&”和 const Duration& 转换为非 const,但这似乎不起作用。我已经尝试了您可以在网上找到的有关同化运算符重载的示例,但这些示例都在模板中重载,而不是在继承的类中,我几乎没有对“_value”的写入权限,这是我应该覆盖的值重新分配指针。

谢谢

编辑:

 struct __declspec(empty_bases)Time : tagged<uint64_t, Time>, ordered<Time>, show_value<Time, int>
    {
        using tagged::tagged;

        Time& operator+(const Duration& right) {
            Time t = Time(value(*this) + value(right));
            return t;
        };

        Time& operator+=(const Duration& right) {
            (uint64_t&)(*this) = value(*this) + value(right);
            return (*this);
        };

    };


    //Duration
    struct __declspec(empty_bases)Duration : tagged<uint64_t, Duration>, ordered<Duration>, show_value<Duration, int> {
        using tagged::tagged;

        Duration& operator+(const Duration& right) {
            Duration d = Duration(value(*this) + value(right));
            return d;
        };

        Time& operator+(const Time & right) {
            Time t = Time(value(*this) + value(right));
            return t;
        };

        Duration& operator-(const Time & right) {
            Duration d = Duration(value(*this) - value(right));
            return d;
        };

        Duration& operator-(const Duration & right) {
            Duration d = Duration(value(*this) - value(right));
            return d;
        };

         Duration& operator+=(const Duration& right) {
             (uint64_t&)(*this) = (uint64_t&)(*this) + (uint64_t&)(right);
             return (*this);
        }

         Duration& operator-=(const Duration& right) {
            (uint64_t&)(*this) = value(*this) - value(right);
            return (*this);
                };
            };

这就是我现在所拥有的。仍然有不断弹出的相同语法错误。我不知道lmao了

C++ 模板 重载 assignment-operator

评论

0赞 Oliv 5/25/2019
例如,在类的正文中,addTimeTime& opeartor+=(const Time& other){value+=other.value;return *this;}
0赞 Comedian6969 5/25/2019
@Oliv但在 Time 的正文中,我只能访问 value() 而不是 value,因为它是模板中的私有成员
0赞 Oliv 5/25/2019
您可以通过这种方式获取值。在您的特定情况下,它将起作用。(uint64_t&)(*this)

答:

0赞 Massimo Castrioto 5/25/2019 #1

据我所知,您应该能够使用 value() 函数实现它;由于值通过引用返回,因此应该可以像这样工作:

Duration & operator+=(const Duration & right) {
    value(*this) += value( right );
    return *this;
}

请注意其他运算符(我正在查看 + 和 -),因为您返回对时态对象的引用。

Duration & operator+(const Duration & right) {                // this returns a reference to an object
  Duration d = Duration( value( *this ) + value( right ) );   // this creates a temporal variable
  return d;                                                   // you return a reference to d bu its lifetime is over -> undefined behavior I believe
}