Add ways to construct cluster structs from the shared superclass. (#26763)

* Add ways to construct cluster structs from the shared superclass.

This is only relevant when a struct is being shared across multiple clusters.

* Address review comment.
diff --git a/src/app/zap-templates/templates/app/cluster-objects.zapt b/src/app/zap-templates/templates/app/cluster-objects.zapt
index e8ffcc3..fbe6e0a 100644
--- a/src/app/zap-templates/templates/app/cluster-objects.zapt
+++ b/src/app/zap-templates/templates/app/cluster-objects.zapt
@@ -58,13 +58,29 @@
 
 using Fields = Clusters::detail::Structs::{{asUpperCamelCase name}}::Fields;
 
+// This is a struct type shared across multiple clusters.  Create a type-safe
+// declaration in this cluster namespace (so not just pulling in the shared
+// implementation via "using", but make sure we can initialize our
+// Type/DecodableType from the generic Type/DecodableType as needed.
 struct Type : public Clusters::detail::Structs::{{asUpperCamelCase name}}::Type
 {
+private:
+    using Super = Clusters::detail::Structs::{{asUpperCamelCase name}}::Type;
+public:
+    constexpr Type() = default;
+    constexpr Type(const Super & arg) : Super(arg) {}
+    constexpr Type(Super && arg) : Super(std::move(arg)) {}
 };
 
 {{#if struct_contains_array}}
 struct DecodableType : public Clusters::detail::Structs::{{asUpperCamelCase name}}::DecodableType
 {
+private:
+    using Super = Clusters::detail::Structs::{{asUpperCamelCase name}}::DecodableType;
+public:
+    DecodableType() = default;
+    DecodableType(const Super & arg) : Super(arg) {}
+    DecodableType(Super && arg) : Super(std::move(arg)) {}
 };
 {{else}}
 using DecodableType = Type;
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h
index 8ce9f49..6a4a294 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h
@@ -13180,8 +13180,19 @@
 
 using Fields = Clusters::detail::Structs::LabelStruct::Fields;
 
+// This is a struct type shared across multiple clusters.  Create a type-safe
+// declaration in this cluster namespace (so not just pulling in the shared
+// implementation via "using", but make sure we can initialize our
+// Type/DecodableType from the generic Type/DecodableType as needed.
 struct Type : public Clusters::detail::Structs::LabelStruct::Type
 {
+private:
+    using Super = Clusters::detail::Structs::LabelStruct::Type;
+
+public:
+    constexpr Type() = default;
+    constexpr Type(const Super & arg) : Super(arg) {}
+    constexpr Type(Super && arg) : Super(std::move(arg)) {}
 };
 
 using DecodableType = Type;
@@ -13267,8 +13278,19 @@
 
 using Fields = Clusters::detail::Structs::LabelStruct::Fields;
 
+// This is a struct type shared across multiple clusters.  Create a type-safe
+// declaration in this cluster namespace (so not just pulling in the shared
+// implementation via "using", but make sure we can initialize our
+// Type/DecodableType from the generic Type/DecodableType as needed.
 struct Type : public Clusters::detail::Structs::LabelStruct::Type
 {
+private:
+    using Super = Clusters::detail::Structs::LabelStruct::Type;
+
+public:
+    constexpr Type() = default;
+    constexpr Type(const Super & arg) : Super(arg) {}
+    constexpr Type(Super && arg) : Super(std::move(arg)) {}
 };
 
 using DecodableType = Type;
@@ -27013,8 +27035,19 @@
 
 using Fields = Clusters::detail::Structs::ApplicationStruct::Fields;
 
+// This is a struct type shared across multiple clusters.  Create a type-safe
+// declaration in this cluster namespace (so not just pulling in the shared
+// implementation via "using", but make sure we can initialize our
+// Type/DecodableType from the generic Type/DecodableType as needed.
 struct Type : public Clusters::detail::Structs::ApplicationStruct::Type
 {
+private:
+    using Super = Clusters::detail::Structs::ApplicationStruct::Type;
+
+public:
+    constexpr Type() = default;
+    constexpr Type(const Super & arg) : Super(arg) {}
+    constexpr Type(Super && arg) : Super(std::move(arg)) {}
 };
 
 using DecodableType = Type;
@@ -27299,8 +27332,19 @@
 
 using Fields = Clusters::detail::Structs::ApplicationStruct::Fields;
 
+// This is a struct type shared across multiple clusters.  Create a type-safe
+// declaration in this cluster namespace (so not just pulling in the shared
+// implementation via "using", but make sure we can initialize our
+// Type/DecodableType from the generic Type/DecodableType as needed.
 struct Type : public Clusters::detail::Structs::ApplicationStruct::Type
 {
+private:
+    using Super = Clusters::detail::Structs::ApplicationStruct::Type;
+
+public:
+    constexpr Type() = default;
+    constexpr Type(const Super & arg) : Super(arg) {}
+    constexpr Type(Super && arg) : Super(std::move(arg)) {}
 };
 
 using DecodableType = Type;