Как вернуть std :: set с частным компаратором - PullRequest
0 голосов
/ 03 апреля 2009

Я хотел бы написать (C ++) метод, который возвращает std :: набор пользовательских объектов. Однако я не хочу показывать компаратор, используемый при вставке объектов, поэтому я делаю его закрытым классом. Я создаю набор так:

std::set<some_class, some_class_comparator> return_object;

Теперь я хочу вернуть набор, поэтому он должен быть разыгран следующим образом (неявно при возврате):

(const std::set<some_class>) return_object;

Здесь компилятор жалуется. Есть ли способ привести изменяемый набор с компаратором к неизменяемому без?

спасибо большое,

Хольгер

Ответы [ 6 ]

4 голосов
/ 03 апреля 2009

Есть ли способ разыграть изменяемый набор? с компаратором неизменным без

Нет, потому что

std::set<some_class, some_class_comparator>

и

std::set<some_class>

разные, совершенно не связанные типы. Шаблоны - это просто шаблоны, способ указать, как должен быть сгенерирован тип перед компиляцией. Во втором случае компаратор является компаратором по умолчанию, с которым поставляется std :: set.

Есть ли убедительная причина, по которой some_class_comparotor должен быть закрытым? Может ли это быть своей собственной самостоятельной сущностью? Разве вы не хотите загрязнять публичный интерфейс вашего класса?

1 голос
/ 03 апреля 2009

Ваше лучшее решение - что-то вроде этого:

class MyClass
{
    class some_class_comparator;
public:
    typedef std::set<int, some_class_comparator> ReturnSet;
    ReturnSet myMethod();
    // ...
private:
    class some_class_comparator
    {
    public:
        bool operator< (MyClass& m) {return true;}
    };
};

//later...
MyClass::ReturnSet s = my_class_instance.myMethod();
1 голос
/ 03 апреля 2009

Я так не думаю. AFAIK std::set<some_class> это просто сокращение для std::set<some_class, std::less<some_class> >, поэтому набор не может быть преобразован так, как вы хотите.

Я предлагаю перенести элементы в некоторую другую структуру данных (например, вектор), которая будет поддерживать текущие элементы в порядке без необходимости в компараторе.

0 голосов
/ 03 апреля 2009

STL поставляется с множеством встроенных классов, но это также расширяемая среда. Если вы определите свой :: own :: immutable_set с определенными итераторами, другие алгоритмы STL могут использовать его. immutable_set<T> будет определяться как тонкая константная оболочка вокруг изменяемого std::set<T, comparator<T> > (некоторая магия шаблона требуется для поддержки разных компараторов, так как они приводят к разным типам). immutable_set<T>::iterator::operator++ будет перенаправлять на std::set<T>::iterator::operator++ и т. Д.

0 голосов
/ 03 апреля 2009

Вы хотите скрыть детали реализации от вызывающей стороны, которая не похожа на шаблон, которая звучит как виртуальные функции. Во-первых, я должен спросить себя, действительно ли это имеет значение? Если это так, спрячьте свой класс за интерфейсом IOpaqueSet. Конечно, тогда никакие другие операции STL не могли работать с ним.

0 голосов
/ 03 апреля 2009

Это два разных типа std :: и std :: set .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...