Задать вопрос
Dyikot
@Dyikot

Почему возникает ошибка при вызове вирутального метода в «operator=»?

Есть следующий класс:
template<typename T, typename TInput = T>
    requires std::convertible_to<TInput, T> && std::copyable<T>
class StylyableProperty
{
public:
    using Type = T;
    using InputType = TInput;
protected:
    T _value;
public:
    StylyableProperty() requires std::default_initializable<T>:
        _value()
    {}

    StylyableProperty(TInput value):
        _value(value)
    {}

    StylyableProperty(const StylyableProperty& other): 
        _value(other._value)
    {}

    StylyableProperty(StylyableProperty&& other) noexcept:
        _value(std::move(other._value))
    {}

    virtual ~StylyableProperty() = default;

    virtual void Set(TInput value)
    {
        _value = value;
    }

    virtual TInput Get() const
    { 
        return _value; 
    }

    operator TInput() const
    { 
        return Get();
    }

    StylyableProperty& operator=(TInput value)
    {
        Set(value);
        return *this;
    }

    StylyableProperty& operator=(const StylyableProperty& other)
    {
        _value = other._value;
        return *this;
    }

    StylyableProperty& operator=(StylyableProperty&& other) noexcept
    {
        _value = std::move(other._value);
        return *this;
    }

    const T* operator->() const { return &_value; }
};


И есть класс переопределяющий метод Set:
class WidthProperty: public StylyableProperty<float>
{
private:
	UIElement& _owner;
public:
	WidthProperty(UIElement& owner):
		StylyableProperty<float>(0),
		_owner(owner)
	{}

	void Set(float value) override
	{
		_value = value;
		_owner._actualWidth = value - _owner.Margin->Right;
		_owner.OnSizeChanged();
	}
};


И в следующем примере:
UIElement e;
e.Width = 100; // no operator "=" matches these operands
e.Width.Set(100); // ok
  • Вопрос задан
  • 36 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Во-первых, оператор не виртуальный.

Во-вторых, это проблема из-за правил поиска операторов. Они ищутся только в типах, которые участвуют в выражении, т.е. int и WidthProperty.

Если хотите использовать оператор из родительского класса, надо в дочернем сделать
using Base::operator=;

Что бы протащить этот метод в пространство имен дочернего класса, где компилятор его найдет.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы