Сравнение std:: функции для равенства?

как я могу сравнить два C++11 std::functionс operator==, и return true если оба сказал functions относятся к тому же указателю функции?

5 ответов


оператор== на std:: function сравнить std:: function С нулевым указателем, насколько я могу судить стандарт не предоставляет никаких подробностей, почему.

хотя, это повышение FAQ запись,почему я не могу сравнить объекты boost:: function с оператором== или оператором!=? предоставляет обоснование и, насколько я могу судить, должно быть применимо к std:: function Как хорошо. Цитируя FAQ:

сравнение между объектами boost:: function не может быть реализовано "хорошо" и, следовательно, не будет реализовано. [...]

затем он описывает запрошенные решения, похожие на Preet, и продолжает говорить:

проблема возникает, когда тип объектов функции, хранящихся как f, так и g, не имеет оператора==[...]

и объясняет, почему это должно быть рассмотрено в операторе присваивания или конструкторе а потом говорит:

все эти проблемы переводятся в сбои в конструкторах функций boost::или операторе присваивания, даже если пользователь никогда не вызывает operator==. Мы не можем так поступать с пользователями.

обновление

нашел обоснование стандартов в доступ к цели объекта tr1::function, который довольно старый, но согласуется с FAQ boost и говорит:

operator== невозможно для функции tr1:: в языке C++, потому что у нас нет надежного способа определить, является ли данный тип T равенством, сопоставимым без помощи пользователя.


вы действительно можете заставить его работать с .target:

template<typename T, typename... U>
size_t getAddress(std::function<T(U...)> f) {
    typedef T(fnType)(U...);
    fnType ** fnPointer = f.template target<fnType*>();
    return (size_t) *fnPointer;
}

if (getAddress(f) == getAddress(g)) {...}

(Ref:C++ пытается получить адрес функции из std:: function)


вы можете попробовать сравнить a и b сначала сравнив их .target_type() и если эти идентификаторы целевого типа одинаковы, то вы можете сравнить их .target() указатели. Вы можете использовать несоответствующий целевой тип как раннее значение false.


Если std::function<T(U...)> f является функцией-членом,fnPointer будет null.


имейте в виду, что равенство функций является неразрешимой проблемой в лямбда-исчислении (и именно поэтому многие языки программирования запрещают сравнивать функции).

, даже если == test compiles, это было бы самое большее просто проверить, что код идентичен (имеет тот же адрес), а не то, что сравниваемые функции имеют одинаковое поведение.