[libcamera-devel] libcamera: controls: Disable ControlValue<T> construction from unsupported T
diff mbox series

Message ID 20201023220020.22536-1-laurent.pinchart@ideasonboard.com
State Accepted
Commit 581bb274956fcf7e781384342e88cd8fa35b1336
Headers show
Series
  • [libcamera-devel] libcamera: controls: Disable ControlValue<T> construction from unsupported T
Related show

Commit Message

Laurent Pinchart Oct. 23, 2020, 10 p.m. UTC
The ControlValue<T> constructor for non-array values is a template
function that participates in overload resolution for all T types that
are not Span or std::string. Other T types that are not supported then
result in a compilation error.

This causes issues when calling an overloaded function that can accept
both a ControlValue and a Span with an std::array<U> parameter. The
first overload will be resolved using implicit construction of a
ControlValue from the std::array<U>, while the second overload will be
resolved using implicit construction of a Span<U> from the
std::array<U>. This results in a compilation error due to an ambiguous
function call.

The first overload is invalid, selecting it would result in a
compilation error in the ControlValue constructor, as the
ControlValue<T> constructor doesn't support std::array<U> for type T.
The compiler can't know about that, as overload resolution happens
earlier.

To fix it, we can disable the ControlValue<T> constructor for
unsupported types T, moving the type check from compilation of the
function to overload resolution. The constructor will not participate in
overload resolution, and the call won't be ambiguous. The end result is
the same for unsupported types, compilation will fail.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 include/libcamera/controls.h | 1 +
 1 file changed, 1 insertion(+)

Comments

Jacopo Mondi Oct. 24, 2020, 4:33 p.m. UTC | #1
Hi Laurent,

On Sat, Oct 24, 2020 at 01:00:20AM +0300, Laurent Pinchart wrote:
> The ControlValue<T> constructor for non-array values is a template
> function that participates in overload resolution for all T types that
> are not Span or std::string. Other T types that are not supported then
> result in a compilation error.
>
> This causes issues when calling an overloaded function that can accept
> both a ControlValue and a Span with an std::array<U> parameter. The
> first overload will be resolved using implicit construction of a
> ControlValue from the std::array<U>, while the second overload will be
> resolved using implicit construction of a Span<U> from the
> std::array<U>. This results in a compilation error due to an ambiguous
> function call.
>
> The first overload is invalid, selecting it would result in a
> compilation error in the ControlValue constructor, as the
> ControlValue<T> constructor doesn't support std::array<U> for type T.
> The compiler can't know about that, as overload resolution happens
> earlier.

mind->bend();

:)

>
> To fix it, we can disable the ControlValue<T> constructor for
> unsupported types T, moving the type check from compilation of the
> function to overload resolution. The constructor will not participate in
> overload resolution, and the call won't be ambiguous. The end result is
> the same for unsupported types, compilation will fail.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Thanks, this should solve the issue I had with ControlInfo()
constructor that took a Span<ControlValue>

Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>

Thanks
  j

> ---
>  include/libcamera/controls.h | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
> index 3d7f4b0dc1a7..3b7f3347761e 100644
> --- a/include/libcamera/controls.h
> +++ b/include/libcamera/controls.h
> @@ -97,6 +97,7 @@ public:
>
>  #ifndef __DOXYGEN__
>  	template<typename T, typename std::enable_if_t<!details::is_span<T>::value &&
> +						       details::control_type<T>::value &&
>  						       !std::is_same<std::string, std::remove_cv_t<T>>::value,
>  						       std::nullptr_t> = nullptr>
>  	ControlValue(const T &value)
> --
> Regards,
>
> Laurent Pinchart
>

Patch
diff mbox series

diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
index 3d7f4b0dc1a7..3b7f3347761e 100644
--- a/include/libcamera/controls.h
+++ b/include/libcamera/controls.h
@@ -97,6 +97,7 @@  public:
 
 #ifndef __DOXYGEN__
 	template<typename T, typename std::enable_if_t<!details::is_span<T>::value &&
+						       details::control_type<T>::value &&
 						       !std::is_same<std::string, std::remove_cv_t<T>>::value,
 						       std::nullptr_t> = nullptr>
 	ControlValue(const T &value)