summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-01-03 01:42:51 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-01-03 16:29:02 +0200
commit1acad98f7d162ee4e9d5f869489b0c3b17ad80aa (patch)
treeee5e62a90b4637584140a1e75765c8195422ef13
parent7141ac74fd282cfe62de1a61a1f0edaee3c14d8e (diff)
libcamera: object: Support reference arguments in invokeMethod()
Invoking a method that takes a reference argument with Object::invokeMethod() results in a compilation error: ../test/object-invoke.cpp:131:11: error: no matching member function for call to 'invokeMethod' object_.invokeMethod(&InvokedObject::methodWithReference, ~~~~~~~~^~~~~~~~~~~~ ../include/libcamera/object.h:33:7: note: candidate template ignored: deduced conflicting types for parameter 'Args' (<const int &> vs. <int>) void invokeMethod(void (T::*func)(Args...), ConnectionType type, Args... args) This is due to the fact that implicit type conversions (from value to reference in this case) takes place after template argument type deduction, during overload resolution. A similar issue would occur if T::func took a long argument and invokeMethod() was called with an in argument. Fix this by specifying to sets of argument types in the invokeMethod() template, one for the arguments to the invoked method, and one for the arguments to invokeMethod() itself. The compiler can then first perform type deduction separately, and implicit conversion in a second step. Reported-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
-rw-r--r--include/libcamera/object.h10
1 files changed, 6 insertions, 4 deletions
diff --git a/include/libcamera/object.h b/include/libcamera/object.h
index 86e0f726..21b70460 100644
--- a/include/libcamera/object.h
+++ b/include/libcamera/object.h
@@ -29,13 +29,15 @@ public:
void postMessage(std::unique_ptr<Message> msg);
- template<typename T, typename... Args, typename std::enable_if<std::is_base_of<Object, T>::value>::type * = nullptr>
- void invokeMethod(void (T::*func)(Args...), ConnectionType type, Args... args)
+ template<typename T, typename... FuncArgs, typename... Args,
+ typename std::enable_if<std::is_base_of<Object, T>::value>::type * = nullptr>
+ void invokeMethod(void (T::*func)(FuncArgs...), ConnectionType type,
+ Args... args)
{
T *obj = static_cast<T *>(this);
BoundMethodBase *method =
- new BoundMemberMethod<T, Args...>(obj, this, func, type);
- void *pack = new typename BoundMemberMethod<T, Args...>::PackType{ args... };
+ new BoundMemberMethod<T, FuncArgs...>(obj, this, func, type);
+ void *pack = new typename BoundMemberMethod<T, FuncArgs...>::PackType{ args... };
method->activatePack(pack, true);
}