Как сравнить два С++ 11 std::function
с operator==
и вернуть true
, если оба указанных function
относятся к одному и тому же указателю функции?
Сравнение std:: функций для равенства?
Ответ 1
operator == для std:: function сравнивает std:: function с нулевым указателем, насколько я могу сказать, что стандарт не сообщать какие-либо подробности о том, почему.
Несмотря на то, что это увеличение часто задаваемых вопросов, Почему я не могу сравнивать объекты boost:: function с оператором == или оператором! =? обоснование и, насколько я могу судить, должно быть применимо к std:: function. Часто задаваемые вопросы:
Сравнение объектов boost:: function не может быть реализовано "хорошо" и поэтому не будет реализовано. [...]
он затем описывает запрошенные решения, подобные Preet, и продолжает:
Проблема возникает, когда тип объектов функции, хранящихся как f, так и g, не имеет оператора == [...]
и объясняет, почему это должно быть рассмотрено либо в операторе присваивания, либо в конструкторе, а затем продолжает:
Все эти проблемы переходят в сбои в конструкторы boost:: function или оператор присваивания, даже если пользователь никогда не вызывает operator ==. Мы не можем сделать это для пользователей.
Обновить
Обнаружено обоснование стандартов в Доступ к объекту объекта функции tr1::, который довольно старый, но совместим с частотами и говорит:
operator == не реализуется для tr1:: function внутри языка С++, потому что у нас нет надежного способа определить, является ли данный тип T равным равенству Comparable без помощи пользователя.
Ответ 2
Вы можете заставить его работать с .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)) {...}
(Ссылка: С++ пытается получить адрес функции из std:: function)
Ответ 3
Сначала вы можете сравнить a
и b
, сравнив их .target_type()
и, если эти идентификаторы целевого типа совпадают, то вы можете сравнить их .target()
указатели. Вы можете использовать несоответствующий целевой тип как ранний из ложных.
Ответ 4
Если std::function<T(U...)> f
является функцией-членом, fnPointer
будет иметь значение null.
Ответ 5
Имейте в виду, что равенство функций является неразрешимой проблемой в лямбда-исчислении (и поэтому многие языки программирования запрещают сравнивать функции).
Таким образом, даже если компиляция ==
компилируется, она просто проверит, что код идентичен (имеет тот же адрес), а не то, что сравниваемые функции имеют одинаковое поведение.
Ответ 6
Различные методы привязки, типы функций разные. Например: Если std::function<void(int)>func = bind(&test::print, ref(t), placeholders::_1);
, для целевой функции std будет std::_Bind<std::_Mem_fn<void(test::*)(int)>(std::reference_wrapper<test>, std::_Placeholder<1>)>
. Но исходный адрес функции - первая переменная частного члена в bind
. Если вам нужно получить свой адрес, возможно, вы можете получить его по смещению памяти. Исходный адрес функции может указывать на то, что они равны. Мой английский очень плохой, я не знаю, как четко выражать. Надеюсь, это будет полезно для вас.