Правильное поведение при перегрузке приводит к тому, что класс ведет себя идентично указателям - PullRequest
3 голосов
/ 02 декабря 2011

Я хочу, чтобы класс вел себя идентично указателям, , но также поддерживает операторы сравнения, такие как < и >.

Я сталкиваюсь с проблемами приведения:1007 *

ptr_t<foo> x = new foo;
(bar*)x;              // cast should be allowed
static_cast<bar*>(x); // cast should fail

Приведенный выше фрагмент должен вести себя так, как если бы ptr_t<foo> было foo*.

Вот оператор приведения:

template <typename cast_t>
explicit inline operator cast_t() {
  return (cast_t)(ptr); // causes static_cast to use C-style, which is bad
}

Если я использую стиль C в определении, тогда static_cast становится небезопасным.Если я использую static_cast, то стиль C становится менее полезным.Как я могу это исправить?

Ответы [ 3 ]

2 голосов
/ 02 декабря 2011

Вы можете легко эмулировать ptr_t<foo>, действуя как foo*, перегружая операторы стрелок и разыменования, одновременно предоставляя функцию get.Так работают все умные указатели (по соглашению), и с ними гораздо естественнее работать.Бездельничать с кастами кажется излишне сложным и хрупким.

template <typename T>
struct ptr_t
{
    T* get() const;

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

    T& operator*() const
    {
        return *get();
    }
};

struct foo
{
    void bar() const;
};

void baz(foo*);

ptr_t<foo> x = /* .. */;

x->bar();
(*x).bar();
baz(x.get());
1 голос
/ 02 декабря 2011

Это не решение моей собственной проблемы, но я понял, что это может быть полезно для будущих зрителей:

template<typename t>
using ptr_t = t*;

Это приведет к тому, что ptr_t<foo> будет вести себя идентично foo* (технически это тот же тип)

К сожалению, мне нужно перегрузить < и >, чтобы они отличались от обычного указателя, и поэтому в моем случае это не работает.

0 голосов
/ 03 декабря 2011

Я хочу, чтобы класс вел себя идентично указателям, но

Ваши требования явно не могут быть выполнены:

Если он ведет себя как указатель, это указатель.

Итак, это не класс, вы не можете определить перегрузки и т. Д.

Удивительно, но это обычный вопрос, если вы заменяете какой-либо другой тип на «указатели».

...