diff --git a/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl b/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl
index 3942e5708..93f988cd9 100644
--- a/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl
+++ b/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl
@@ -16,6 +16,8 @@

 {% if has_map %}#include <map>{% endif %}
 {% if has_string %}#include <string>{% endif %}
+#include <type_traits>
+#include <utility>
 {% if has_array %}#include <vector>{% endif %}

 #include <libcamera/controls.h>
diff --git a/utils/codegen/ipc/generators/libcamera_templates/definition_functions.tmpl b/utils/codegen/ipc/generators/libcamera_templates/definition_functions.tmpl
index 3a57a3c2c..dec25558f 100644
--- a/utils/codegen/ipc/generators/libcamera_templates/definition_functions.tmpl
+++ b/utils/codegen/ipc/generators/libcamera_templates/definition_functions.tmpl
@@ -28,14 +28,21 @@ public:
 #ifndef __DOXYGEN__
 	{{struct.mojom_name}}() = default;

+	template<
+	{%- for field in struct.fields %}
+		typename T{{loop.index}} = {{field|name}},
+	{%- endfor %}
+	{%- for field in struct.fields %}
+		std::enable_if_t<std::is_convertible_v<T{{loop.index}}&&, {{field|name}}>> * = nullptr{{"," if not loop.last}}
+	{%- endfor %}
+	>
 	{{struct.mojom_name}}(
 {%- for field in struct.fields -%}
-{{"const " if not field|is_pod}}{{field|name}} {{"&" if not field|is_pod}}_{{field.mojom_name}}{{", " if not loop.last}}
+		T{{loop.index}} &&_{{field.mojom_name}}{{ ", " if not loop.last }}
 {%- endfor -%}
 )
-		:
-{%- for field in struct.fields -%}
-{{" " if loop.first}}{{field.mojom_name}}(_{{field.mojom_name}}){{", " if not loop.last}}
+{%- for field in struct.fields %}
+		{{": " if loop.first else ", "}}{{field.mojom_name}}(std::forward<T{{loop.index}}>(_{{field.mojom_name}}))
 {%- endfor %}
 	{
 	}
diff --git a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl
index 5d70ea6a2..3913eb1fb 100644
--- a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl
+++ b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl
@@ -16,6 +16,8 @@

 {% if has_map %}#include <map>{% endif %}
 {% if has_string %}#include <string>{% endif %}
+#include <type_traits>
+#include <utility>
 {% if has_array %}#include <vector>{% endif %}

 #include <libcamera/base/flags.h>
