diff --git a/include/libcamera/internal/value_node.h b/include/libcamera/internal/value_node.h
index e42aa9ba0ce0..a7f916e22bc8 100644
--- a/include/libcamera/internal/value_node.h
+++ b/include/libcamera/internal/value_node.h
@@ -143,6 +143,14 @@ public:
 #endif /* __DOXYGEN__ */
 
 	ValueNode();
+
+	template<typename T>
+	ValueNode(T &&value)
+		: type_(Type::Empty)
+	{
+		set(std::forward<T>(value));
+	}
+
 	~ValueNode();
 
 	bool isValue() const
diff --git a/src/libcamera/value_node.cpp b/src/libcamera/value_node.cpp
index 52ccf432fb96..6c9e2239165b 100644
--- a/src/libcamera/value_node.cpp
+++ b/src/libcamera/value_node.cpp
@@ -44,6 +44,13 @@ ValueNode::ValueNode()
 {
 }
 
+/**
+ * \fn template<typename T> ValueNode::ValueNode(T &&value)
+ * \brief Construct a ValueNode instance with a value
+ * \tparam T Type of the value
+ * \param[in] value The value
+ */
+
 ValueNode::~ValueNode() = default;
 
 /**
