Это чистое решение для JavaScript без каких-либо библиотек или плагинов:
document.addEventListener('click', function (e) {
if (hasClass(e.target, 'bu')) {
// .bu clicked
// Do your thing
} else if (hasClass(e.target, 'test')) {
// .test clicked
// Do your other thing
}
}, false);
, где hasClass
-
function hasClass(elem, className) {
return elem.className.split(' ').indexOf(className) > -1;
}
Кредит относится к Dave и Sime Vidas
Использование более современных JS, hasClass
может быть реализовано как:
function hasClass(elem, className) {
return elem.classList.contains(className);
}
Я собрал воедино решение, которое, кажется, работает и подчиняется правилам полиморфизма.
Секрет в том, чтобы просто вообще не использовать макрос boost::python::args
или BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
(хотя я допускаю, что он не будет поддерживать аргументы ключ-значение в Python как есть).
Просто создайте вспомогательную функцию, которая имеет l-значение, совпадающее с классом, содержащим виртуальную функцию, т.е. X
, и не имеет НИКАКИХ других аргументов, переданных ей. Это избавляет от проблемы Python, не соответствующей сигнатуре метода, потому что параметр a
вместе со значением по умолчанию просто не существует:
A* getItem_noargs_wrap(X& x)
{
return x.getItem();
}
Это кажется бессмысленным, но это совсем не так. Вызов x.getItem()
- от C ++ до C ++, поэтому параметр по умолчанию правильно сопоставляется с пустой подписью.
Однако, когда мы пришли к написанию нашего def()
, мы теперь можем дать Python функцию, которая действительно не принимает аргументов, что позволяет ему соответствовать вызовам getItem()
в Python.
Осталось лишь немного помочь компилятору узнать, какая сигнатура соответствует какому базовому вызову:
.def("getItem",
&getItem_noargs_wrap);
.def("getItem",
&X::getItem,
&X_wrap::default_getItem);
Так что getItem()
дважды предоставляется Python - один раз без аргументов используя нашу вспомогательную функцию для вызова метода правильного экземпляра за кулисами, и однажды взяв Z*
и используя стандартный шаблон для не чистых виртуальных функций.
Второй вызов - сопоставление в действии:
.def<const char* (X::*)(Z*)>("getItem",
Это, кажется, работает хорошо - но я не исчерпывающе проверил, что он каким-то образом не нарушает полиморфизм. 1121]