Запуск оператора приведения при использовании оператора точки

У меня есть класс примерно так:

template<typename T>
class wrapper
{
public:
    operator const T & () const
    {
        return value;
    }
private:
    T value;
};

Затем я использую его с такой структурой:

struct point { float x; float y; };

//...

wrapper<point> myPoint;
std::cout << myPoint.x;// error: no member x or whatever.

Мне интересно, есть ли способ разрешить это без необходимости делать ((point)myPoint).x. Я знаю, что могу перегрузить оператор ->, но я бы предпочел этого не делать, поскольку предполагается, что он «притворяется» не указателем.


person Francisco Ryan Tolmasky I    schedule 03.08.2012    source источник
comment
Вы можете сказать static_cast<point const &>(myPoint).x.   -  person Kerrek SB    schedule 03.08.2012
comment
Вы можете изменить оператор приведения на operator() и использовать myPoint().x;, если вы пытаетесь избежать длины. Однако это имеет меньше смысла, чем operator->.   -  person chris    schedule 03.08.2012


Ответы (2)


Вы можете добиться чего-то похожего с помощью -> вместо .:

template<typename T>
class wrapper
{
public:
    operator const T & () const // will this still be needed now?
    {
        return value;
    }

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

private:
    T value;
};

А потом:

struct point { float x; float y; }

//...

wrapper<point> myPoint; // this needs to be initialised!
std::cout << myPoint->x;
person R. Martinho Fernandes    schedule 03.08.2012
comment
@Mr.Anubis о да, ты прав. Это было скопировано прямо из вопроса. - person R. Martinho Fernandes; 03.08.2012
comment
Это хорошо и все такое, но не лучше ли иметь оператор .GetValue()? - person Johan Lundberg; 03.08.2012
comment
@JohanLundberg Как я мог знать, что имеет больше смысла? Я не знаю, что такое wrapper. - person R. Martinho Fernandes; 03.08.2012
comment
@JohanLundberg: проблема в том, что вы не можете сделать это с .. Среди альтернатив operator->, вероятно, имеет наибольший смысл. - person David Rodríguez - dribeas; 03.08.2012

Вы не можете заставить свой класс-оболочку притворяться настоящим классом, как вы описали. Основная причина в том, что оператор выбора члена (.) не может быть перегружен.

person shargors    schedule 03.08.2012
comment
Немного удивлен, что у этого не было голосов. Это кратко, но ответ так прост... в настоящее время. Продолжается продвижение operator. isocpp.org/blog/2016/02/ Помимо обработки явного доступа с помощью ., предлагается перехватить все доступы (например, operator=), не определенные в классе & перенаправьте их в результат operator. Я беспокоюсь, что эта неявная роль кажется слишком широкой, рискованной, выходящей за рамки ее имени и ленивой: если вы хотите перенаправить операторов, напишите их... Но Бьярне - одно из предложений. авторы, так! - person underscore_d; 07.08.2016