Как перегрузить оператор присваивания для класса, который наследуется от шаблона в C ++ - PullRequest
0 голосов
/ 24 мая 2019

У меня есть помеченный класс утилит. Мне пришлось объявить 2 новые структуры, используя эти классы шаблонов следующим образом.

tagged.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);
    }
};

Это две структуры, которые я объявил, следуя правилам, данным в назначении. primitives.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» к non-consts, но, похоже, это не сработало. Я пробовал примеры, которые вы можете найти в Интернете о перегрузке оператора присваивания, но примеры все перегружены в шаблоне, а не в унаследованном классе, где у меня практически нет доступа на запись к «_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

1 Ответ

0 голосов
/ 25 мая 2019

Из того, что я вижу, вы сможете реализовать это с помощью функции 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...