diff --git a/include/aidge/operator/Add.hpp b/include/aidge/operator/Add.hpp
index 8991a6f5f416270effe837fe3c9ef8bf56ec7297..303092911ae369473c1f3d6b7f122e3068d77028 100644
--- a/include/aidge/operator/Add.hpp
+++ b/include/aidge/operator/Add.hpp
@@ -51,7 +51,7 @@ public:
      * @brief Copy-constructor. Copy the operator parameters and its output tensor(s), but not its input tensors (the new operator has no input associated).
      * @param op Operator to copy.
      */
-    Add_Op(const Add_Op& op)
+    Add_Op(const Add_Op<NUM>& op)
         : Operator(Type),
           mOutput(std::make_shared<Tensor>(*op.mOutput))
     {
@@ -61,6 +61,7 @@ public:
             mInputs[i] = std::make_shared<Tensor>();
         }
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<Add_Op<NUM>>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**
diff --git a/include/aidge/operator/AvgPooling.hpp b/include/aidge/operator/AvgPooling.hpp
index 4f6c2e6ced82e4c700ee4a54d0f4418a6666bd71..2fbff53c30e376e80d07f0859851057177bf0868 100644
--- a/include/aidge/operator/AvgPooling.hpp
+++ b/include/aidge/operator/AvgPooling.hpp
@@ -66,13 +66,14 @@ public:
      * @brief Copy-constructor. Copy the operator parameters and its output tensor(s), but not its input tensors (the new operator has no input associated).
      * @param op Operator to copy.
      */
-    AvgPooling_Op(const AvgPooling_Op& op)
+    AvgPooling_Op(const AvgPooling_Op<DIM>& op)
         : Operator(Type),
           Parameterizable_(op),
           mOutput(std::make_shared<Tensor>(*op.mOutput))
     {
         // cpy-ctor
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<AvgPooling_Op<DIM>>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**
diff --git a/include/aidge/operator/BatchNorm.hpp b/include/aidge/operator/BatchNorm.hpp
index cb22eda33442094beb7f6635183ec19c31fc7162..f1a6ae8f52141839f72211f23511a0607e2138b6 100644
--- a/include/aidge/operator/BatchNorm.hpp
+++ b/include/aidge/operator/BatchNorm.hpp
@@ -66,6 +66,7 @@ public:
     {
         // cpy-ctor
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<BatchNorm_Op<DIM>>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**
diff --git a/include/aidge/operator/Conv.hpp b/include/aidge/operator/Conv.hpp
index 3015069ea67f43d527ce01b99080cbb080ef5230..e95b46ae5583df9e6b471dc4005d0d9c4636ca9b 100644
--- a/include/aidge/operator/Conv.hpp
+++ b/include/aidge/operator/Conv.hpp
@@ -76,6 +76,7 @@ public:
     {
         // cpy-ctor
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<Conv_Op<DIM>>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**
diff --git a/include/aidge/operator/ConvDepthWise.hpp b/include/aidge/operator/ConvDepthWise.hpp
index 3d0e5c93176fbbc652bca0a4b8dee2adcaf73445..12d15328cbabbe5b066fa2fb375adecd7935c889 100644
--- a/include/aidge/operator/ConvDepthWise.hpp
+++ b/include/aidge/operator/ConvDepthWise.hpp
@@ -81,6 +81,7 @@ class ConvDepthWise_Op : public Operator,
     {
         // cpy-ctor
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<ConvDepthWise_Op<DIM>>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**
diff --git a/include/aidge/operator/FC.hpp b/include/aidge/operator/FC.hpp
index c173446943da63c2da9a347d8f4f050fe3215a7c..73cdab54c2cfade6fbd397d33d537b16cb5245f1 100644
--- a/include/aidge/operator/FC.hpp
+++ b/include/aidge/operator/FC.hpp
@@ -67,6 +67,7 @@ public:
     {
         // cpy-ctor
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<FC_Op>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**
diff --git a/include/aidge/operator/GenericOperator.hpp b/include/aidge/operator/GenericOperator.hpp
index 68164dda263c3933690d4d20d57150e4d32ff53f..184100174714df5fc059e374cb85549f6bfd4135 100644
--- a/include/aidge/operator/GenericOperator.hpp
+++ b/include/aidge/operator/GenericOperator.hpp
@@ -159,7 +159,7 @@ class GenericOperator_Op
         if (mComputeOutputDims) {
             return !(mOutputs[0]->empty());
         }
-        else {            
+        else {
             assert(false && "GenericOperator cannot forward dims");
             return false;
         }
diff --git a/include/aidge/operator/LeakyReLU.hpp b/include/aidge/operator/LeakyReLU.hpp
index 2553b46d88b55acea10cf340bf7d982221bdcb8b..dc9548515134a68ad28a8b58213b536cd43fc406 100644
--- a/include/aidge/operator/LeakyReLU.hpp
+++ b/include/aidge/operator/LeakyReLU.hpp
@@ -64,6 +64,7 @@ public:
     {
         // cpy-ctor
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<LeakyReLU_Op>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**
diff --git a/include/aidge/operator/Matmul.hpp b/include/aidge/operator/Matmul.hpp
index fc0032951de6acac7687c752649c811b706b35f3..54bbcb267f346fd79a2b9e3a8aca571ed2e6ba91 100644
--- a/include/aidge/operator/Matmul.hpp
+++ b/include/aidge/operator/Matmul.hpp
@@ -65,6 +65,7 @@ public:
     {
         // cpy-ctor
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<Matmul_Op>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**
diff --git a/include/aidge/operator/MaxPooling.hpp b/include/aidge/operator/MaxPooling.hpp
index 5eff15f723c3c6548c894cffb92d42051fa6704c..775583fd4c2132a5474d136c60c1b53b47ea4c3d 100644
--- a/include/aidge/operator/MaxPooling.hpp
+++ b/include/aidge/operator/MaxPooling.hpp
@@ -67,13 +67,14 @@ public:
      * @brief Copy-constructor. Copy the operator parameters and its output tensor(s), but not its input tensors (the new operator has no input associated).
      * @param op Operator to copy.
      */
-    MaxPooling_Op(const MaxPooling_Op& op)
+    MaxPooling_Op(const MaxPooling_Op<DIM>& op)
         : Operator(Type),
           Parameterizable_(op),
           mOutput(std::make_shared<Tensor>(*op.mOutput))
     {
         // cpy-ctor
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<MaxPooling_Op<DIM>>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**
diff --git a/include/aidge/operator/Operator.hpp b/include/aidge/operator/Operator.hpp
index f99b1e26d38f92b8654de4a49222817fc950ff2c..3ac651cfd6f700a129e36fb461f948f50137cfd6 100644
--- a/include/aidge/operator/Operator.hpp
+++ b/include/aidge/operator/Operator.hpp
@@ -42,6 +42,7 @@ public:
     std::enable_shared_from_this<Operator>()
   {
     mType = op.mType;
+    mImpl = nullptr;
     // Implementation is never cloned. It is up to the non-abstract Operator copy-constructor to create a new implementation matching the copied Operator implementation.
     // See https://gitlab.eclipse.org/eclipse/aidge/aidge_core/-/merge_requests/8#note_1214050 for the discussion.
     // Hooks are not copied.
diff --git a/include/aidge/operator/Producer.hpp b/include/aidge/operator/Producer.hpp
index 937105fbb443c3b7f69087a0517cae371f2eae64..fbab24a0d23712b138c41e969372701fdb3d749e 100644
--- a/include/aidge/operator/Producer.hpp
+++ b/include/aidge/operator/Producer.hpp
@@ -60,6 +60,7 @@ public:
     {
         // cpy-ctor
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<Producer_Op>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**
diff --git a/include/aidge/operator/ReLU.hpp b/include/aidge/operator/ReLU.hpp
index 2f9751a823a79f52280352ae918b156b9375b3f3..cebfa5718886ec26871462f48edcdbc28117da59 100644
--- a/include/aidge/operator/ReLU.hpp
+++ b/include/aidge/operator/ReLU.hpp
@@ -52,6 +52,7 @@ public:
     {
         // cpy-ctor
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<ReLU_Op>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**
diff --git a/include/aidge/operator/Scaling.hpp b/include/aidge/operator/Scaling.hpp
index a2b4091844e545d7d31d97d47def62c41ba14379..e3cba81a490d3b4b28dd3754df7d274eb2e3519a 100644
--- a/include/aidge/operator/Scaling.hpp
+++ b/include/aidge/operator/Scaling.hpp
@@ -66,6 +66,7 @@ public:
     {
         // cpy-ctor
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<Scaling_Op>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**
diff --git a/include/aidge/operator/Softmax.hpp b/include/aidge/operator/Softmax.hpp
index 193fd811b35d07bc045c3ef59e8d62d9b4684613..ffaf0001fbaadf7dc700fca43d77b9998ab26eb2 100644
--- a/include/aidge/operator/Softmax.hpp
+++ b/include/aidge/operator/Softmax.hpp
@@ -52,6 +52,7 @@ public:
     {
         // cpy-ctor
         setDatatype(op.mOutput->dataType());
+        mImpl = op.mImpl ? Registrar<Softmax_Op>::create(mOutput->getImpl()->backend())(*this) : nullptr;
     }
 
     /**