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

Posted

技术标签:

【中文标题】如何为从C++中的模板继承的类重载赋值运算符【英文标题】:How to overload the assignment operator for a class that inherits from a template in c++ 【发布时间】:2019-10-11 08:00:11 【问题描述】:

我标记了一个给定的实用程序模板类。我必须使用这些模板类声明 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

【问题讨论】:

例如在类Time的主体中添加Time&amp; opeartor+=(const Time&amp; other)value+=other.value;return *this; @Oliv 但在 Time 正文中,我只能访问 value() 而不是 value,因为它是模板中的私有成员 你可以通过(uint64_t&amp;)(*this)这种方式获取值。在您的具体情况下,它会起作用。 【参考方案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

【讨论】:

以上是关于如何为从C++中的模板继承的类重载赋值运算符的主要内容,如果未能解决你的问题,请参考以下文章

C++ 继承多态关系中的赋值运算符的重载=operator()

C++ 继承多态关系中的赋值运算符的重载=operator()

C++ - 让派生类从基类“继承”重载赋值运算符的安全/标准方法

C++中的重载赋值运算符

如何为具有自引用指针的类实现复制构造函数/赋值运算符?

c++ 拷贝构造函数与赋值运算符重载函数的区别是