Указатели на функции и методы в std :: set - PullRequest
5 голосов
/ 08 февраля 2012

Как описано в другом моем сообщении , невозможно сравнить 2 указателя на функции-члены с "<" (меньше) </strong>. Или, по крайней мере, это вызывает неопределенное поведение.

Мне только что удалось скомпилировать этот код как с Visual C ++, так и с GCC:

template <class Receiver, class Param = void*, class Return = void>
class EventReceiver : public IFunction<> {

protected:

    std::set< Return(Receiver::*)(Param) > test;
    std::set< Return(*)(Param) > test2;
...

AFAIK, чтобы сделать std :: map или std :: set из чего-либо, должна быть возможность сравнить значения набора с "<". Означает ли это, что вышеупомянутые контейнеры или фактические компиляторы имеют работающую реализацию для сравнения указателей на методы таким образом? </p>

Ответы [ 2 ]

1 голос
/ 10 февраля 2012

Ну, на самом деле вводит в заблуждение , что пример кода скомпилирован. Правда в том, что наборы непригодны . Каждая попытка вставить в них данные приводит к ожидаемой ошибке.

Это «темная сторона» шаблонных функций C ++. Они не существуют до тех пор, пока вы их не используете (и, следовательно, не вызовете ошибок компилятора, пока вы их не сделаете).

Проверьте это:

#include <set>

class X {};

int main() {

    typedef void(X::*FuncPtr)();
    std::set< FuncPtr > set;
    std::less< FuncPtr > less;
    FuncPtr f1;
    FuncPtr f2;
    //set.insert(f1);   // both of these lines
    //less(f1,f2);      // produce an error
};

Удаление комментариев в любой из последних 2 строк приводит к ошибке:

недопустимые операнды типов oid void (X :: * const) () ’и‘ void (X :: *) const) () ’в двоичный оператор <<’ </p>

Скомпилируйте его онлайн здесь .

0 голосов
/ 09 февраля 2012

std::set<T> использует std::less<T> вместо прямого использования оператора меньше. Когда T является типом указателя, std::less<T> гарантированно будет полным заказом, даже если оператор меньше чем.

Редактировать: Раздел 20.3.3 стандарта C ++ 98 говорит "типы указателей", которые (я думаю) включают в себя указатели на функции, но не указатели на элементы.

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