diff --git a/aidge_export_cpp/operators.py b/aidge_export_cpp/operators.py
index 24c2d63c0cc33f5eda845ab7c6c8ec0427016701..6c16f9ec45d0a1bc008ca0302f163f4a734d9dca 100644
--- a/aidge_export_cpp/operators.py
+++ b/aidge_export_cpp/operators.py
@@ -98,56 +98,28 @@ class ReLUCPP(ExportNodeCpp):
 
 
 @operator_register("Conv")
-class ConvCPP(ExportNode):
+class ConvCPP(ExportNodeCpp):
     def __init__(self, node):
         super().__init__(node)
-
-        # self.kernel = node.get_operator().attr.kernel_dims
-        # self.stride = node.get_operator().attr.stride_dims
-        # self.dilation = node.get_operator().attr.dilation_dims
-
         # No padding with Conv
         # Use PaddedConv to add padding attribute
         self.attributes["padding"] = [0, 0]
-
-        # self.nb_channels = node.get_operator().in_channels()
-        # self.nb_outputs = node.get_operator().out_channels()
-
-
-    def export(self, export_folder:Path, list_configs:list):
-
-        copyfile(str(ROOT / "kernels" / "convolution.hpp"),
-                 str(export_folder / "include" / "kernels"))
-        copyfile(str(ROOT / "kernels" / "macs.hpp"),
-                 str(export_folder / "include" / "kernels"))
-        copyfile(str(ROOT / "kernels" / "activation.hpp"),
-                 str(export_folder / "include" / "kernels"))
-
-        list_configs.append("kernels/convolution.hpp")
-        list_configs.append(f"layers/{self.attributes['name']}.h")
-        generate_file(
-            str(export_folder / "layers" / f"{self.attributes['name']}.h"),
-            str(ROOT / "templates" / "configuration" / "convolution_config.jinja"),
-            activation="Linear",
-            rescaling="NoScaling",
-            **self.attributes,
-            )
-
-        return list_configs
-
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            str(ROOT / "templates" / "kernel_forward" / "convolution_forward.jinja"),
-            **self.attributes
-        ))
-        return list_actions
+        self.attributes["activation"] = "Linear"
+        self.attributes["rescaling"] = "NoScaling"
+        self.config_template = str(ROOT / "templates" / "configuration" / "convolution_config.jinja")
+        self.forward_template = str(ROOT / "templates" / "kernel_forward" / "convolution_forward.jinja")
+        self.include_list = []
+        self.kernels_to_copy = [
+            str(ROOT / "kernels" / "convolution.hpp"),
+            str(ROOT / "kernels" / "macs.hpp"),
+            str(ROOT / "kernels" / "activation.hpp"),
+        ]
 
 
 @operator_register("PaddedConv")
-class PaddedConvCPP(ConvCPP):
+class PaddedConvCPP(ExportNodeCpp):
     def __init__(self, node):
-        ExportNode.__init__(self, node)
-
+        super().__init__(node)
         # TODO find a way to retrive attr for meta op
         for n in self.operator.get_micro_graph().get_nodes():
             if n.type() == "Pad":
@@ -156,105 +128,83 @@ class PaddedConvCPP(ConvCPP):
                 self.attributes["kernel_dims"]   = n.get_operator().attr.kernel_dims
                 self.attributes["stride_dims"]   = n.get_operator().attr.stride_dims
                 self.attributes["dilation_dims"] = n.get_operator().attr.dilation_dims
-
+        self.attributes["activation"] = "Linear"
+        self.attributes["rescaling"] = "NoScaling"
+        self.config_template = str(ROOT / "templates" / "configuration" / "convolution_config.jinja")
+        self.forward_template = str(ROOT / "templates" / "kernel_forward" / "convolution_forward.jinja")
+        self.include_list = []
+        self.kernels_to_copy = [
+            str(ROOT / "kernels" / "convolution.hpp"),
+            str(ROOT / "kernels" / "macs.hpp"),
+            str(ROOT / "kernels" / "activation.hpp"),
+        ]
 @operator_register("Add")
-class AddCPP(ExportNode):
+class AddCPP(ExportNodeCpp):
     def __init__(self, node):
         super().__init__(node)
-
-    def export(self, export_folder:str, list_configs:list):
-        list_configs.append(f"layers/{self.attributes['name']}.h")
-        list_configs.append("kernels/elemwise.hpp")
-
-        copyfile(str(ROOT / "kernels" / "elemwise.hpp"),
-                 str(export_folder / "include" / "kernels"))
-        copyfile(str(ROOT / "kernels" / "activation.hpp"),
-                 str(export_folder / "include" / "kernels"))
-
-        generate_file(
-            str(export_folder / "layers" / f"{self.attributes['name']}.h"),
-            str(ROOT / "templates" / "configuration" / "elemwise_config.jinja"),
-            activation="Linear",
-            elemwise_op="Add",
-            rescaling="NoScaling",
-            **self.attributes)
-
-        return list_configs
-
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            str(ROOT / "templates" / "kernel_forward" / "elemwise_forward.jinja"),
-            **self.attributes
-        ))
-        return list_actions
+        self.attributes["elemwise_op"] = "Add"
+        self.attributes["activation"] = "Linear"
+        self.attributes["rescaling"] = "NoScaling"
+        self.config_template = str(ROOT / "templates" / "configuration" / "elemwise_config.jinja")
+        self.forward_template = str(ROOT / "templates" / "kernel_forward" / "elemwise_forward.jinja")
+        self.include_list = []
+        self.kernels_to_copy = [
+            str(ROOT / "kernels" / "elemwise.hpp"),
+            str(ROOT / "kernels" / "activation.hpp"),
+        ]
 
 @operator_register("Sub")
-class SubCPP(ExportNode):
+class SubCPP(ExportNodeCpp):
     def __init__(self, node):
         super().__init__(node)
-
-    def export(self, export_folder:str, list_configs:list):
-        list_configs.append(f"layers/{self.attributes['name']}.h")
-        list_configs.append("kernels/elemwise.hpp")
-        copyfile(str(ROOT / "kernels" / "elemwise.hpp"),
-                 str(export_folder / "include" / "kernels"))
-        copyfile(str(ROOT / "kernels" / "activation.hpp"),
-                 str(export_folder / "include" / "kernels"))
-
-        generate_file(
-            str(export_folder / "layers" / f"{self.attributes['name']}.h"),
-            str(ROOT / "templates" / "configuration" / "elemwise_config.jinja"),
-            activation="Linear",
-            elemwise_op="Sub",
-            rescaling="NoScaling",
-            **self.attributes)
-
-        return list_configs
-
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            str(ROOT / "templates" / "kernel_forward" / "elemwise_forward.jinja"),
-            **self.attributes
-        ))
-        return list_actions
+        self.attributes["elemwise_op"] = "Sub"
+        self.attributes["activation"] = "Linear"
+        self.attributes["rescaling"] = "NoScaling"
+        self.config_template = str(ROOT / "templates" / "configuration" / "elemwise_config.jinja")
+        self.forward_template = str(ROOT / "templates" / "kernel_forward" / "elemwise_forward.jinja")
+        self.include_list = []
+        self.kernels_to_copy = [
+            str(ROOT / "kernels" / "elemwise.hpp"),
+            str(ROOT / "kernels" / "activation.hpp"),
+        ]
 
 @operator_register("Mul")
-class MulCPP(ExportNode):
+class MulCPP(ExportNodeCpp):
     def __init__(self, node):
         super().__init__(node)
+        self.attributes["elemwise_op"] = "Mul"
+        self.attributes["activation"] = "Linear"
+        self.attributes["rescaling"] = "NoScaling"
+        self.config_template = str(ROOT / "templates" / "configuration" / "elemwise_config.jinja")
+        self.forward_template = str(ROOT / "templates" / "kernel_forward" / "elemwise_forward.jinja")
+        self.include_list = []
+        self.kernels_to_copy = [
+            str(ROOT / "kernels" / "elemwise.hpp"),
+            str(ROOT / "kernels" / "activation.hpp"),
+        ]
 
-    def export(self, export_folder:str, list_configs:list):
-        list_configs.append(f"layers/{self.name}.h")
-        list_configs.append("kernels/elemwise.hpp")
-        copyfile(str(ROOT / "kernels" / "elemwise.hpp"),
-                 str(export_folder / "include" / "kernels"))
-        copyfile(str(ROOT / "kernels" / "activation.hpp"),
-                 str(export_folder / "include" / "kernels"))
-
-        generate_file(
-            str(export_folder / "layers" / f"{self.name}.h"),
-            str(ROOT / "templates" / "configuration" / "elemwise_config.jinja"),
-            name=self.name,
-            nb_elts=np.prod(self.inputs_dims[0]),
-            activation="Linear",
-            elemwise_op="Mul",
-            rescaling="NoScaling")
-
-        return list_configs
+@operator_register("MaxPooling")
+class MaxPoolCPP(ExportNodeCpp):
+    def __init__(self, node):
+        super().__init__(node)
 
-    def forward(self, list_actions:list):
-        if not self.is_last:
-            list_actions.append(set_up_output(self.name, "float"))
+        # No padding with MaxPooling
+        # Use PaddedMaxPooling to add padding attribute
+        self.attributes["padding"] = [0, 0]
+        self.attributes["pool_type"] = "Max"
+        self.attributes["activation"] = "Linear"
 
-        list_actions.append(generate_str(
-            str(ROOT / "templates" / "kernel_forward" / "elemwise_forward.jinja"),
-            **self.attributes
-        ))
-        return list_actions
+        self.config_template = str(ROOT / "templates" / "configuration" / "pooling_config.jinja")
+        self.forward_template = str(ROOT / "templates" / "kernel_forward" / "pooling_forward.jinja")
+        self.include_list = []
+        self.kernels_to_copy = [
+            str(ROOT / "kernels" / "pooling.hpp"),
+            str(ROOT / "kernels" / "activation.hpp"),
+        ]
 
 
 @operator_register("PaddedMaxPooling")
-class PaddedMaxPoolCPP(ExportNode):
+class PaddedMaxPoolCPP(ExportNodeCpp):
     def __init__(self, node):
         super().__init__(node)
         for n in self.operator.get_micro_graph().get_nodes():
@@ -263,66 +213,19 @@ class PaddedMaxPoolCPP(ExportNode):
             if n.type() == "MaxPooling":
                 self.attributes["kernel_dims"] = n.get_operator().attr.kernel_dims
                 self.attributes["stride_dims"] = n.get_operator().attr.stride_dims
+        self.attributes["pool_type"] = "Max"
+        self.attributes["activation"] = "Linear"
 
-    def export(self, export_folder:Path, list_configs:list):
-
-        copyfile(str(ROOT / "kernels" / "pooling.hpp"),
-                 str(export_folder / "include" / "kernels"))
-
-        list_configs.append("kernels/pooling.hpp")
-        list_configs.append(f"layers/{self.attributes['name']}.h")
-
-        generate_file(
-            str(export_folder / "layers" / f"{self.attributes['name']}.h"),
-            str(ROOT / "templates" / "configuration" / "pooling_config.jinja"),
-            pool_type="Max",
-            activation="Linear",
-            **self.attributes)
-
-        return list_configs
-
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            str(ROOT / "templates" / "kernel_forward" / "pooling_forward.jinja"),
-            **self.attributes
-        ))
-        return list_actions
-
-@operator_register("MaxPooling")
-class MaxPoolCPP(ExportNode):
-    def __init__(self, node):
-        super().__init__(node)
-
-        # No padding with MaxPooling
-        # Use PaddedMaxPooling to add padding attribute
-        self.attributes["padding"] = [0, 0]
-
-    def export(self, export_folder:Path, list_configs:list):
-
-        copyfile(str(ROOT / "kernels" / "pooling.hpp"),
-                 str(export_folder / "include" / "kernels"))
-
-        list_configs.append("kernels/pooling.hpp")
-        list_configs.append(f"layers/{self.attributes['name']}.h")
-
-        generate_file(
-            str(export_folder / "layers" / f"{self.attributes['name']}.h"),
-            str(ROOT / "templates" / "configuration" / "pooling_config.jinja"),
-            pool_type="Max",
-            activation="Linear",
-            **self.attributes)
-
-        return list_configs
-
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            str(ROOT / "templates" / "kernel_forward" / "pooling_forward.jinja"),
-            **self.attributes
-        ))
-        return list_actions
+        self.config_template = str(ROOT / "templates" / "configuration" / "pooling_config.jinja")
+        self.forward_template = str(ROOT / "templates" / "kernel_forward" / "pooling_forward.jinja")
+        self.include_list = []
+        self.kernels_to_copy = [
+            str(ROOT / "kernels" / "pooling.hpp"),
+            str(ROOT / "kernels" / "activation.hpp"),
+        ]
 
 @operator_register("GlobalAveragePooling")
-class GlobalAveragePoolCPP(ExportNode):
+class GlobalAveragePoolCPP(ExportNodeCpp):
     def __init__(self, node):
         super().__init__(node)
 
@@ -334,64 +237,29 @@ class GlobalAveragePoolCPP(ExportNode):
             self.attributes["in_height"][0],
             self.attributes["in_width"][0],
         ]
+        self.attributes["pool_type"] = "Average"
+        self.attributes["activation"] = "Linear"
 
-    def export(self, export_folder:Path, list_configs:list):
-
-        copyfile(str(ROOT / "kernels" / "pooling.hpp"),
-                 str(export_folder / "include" / "kernels"))
-
-        list_configs.append("kernels/pooling.hpp")
-        list_configs.append(f"layers/{self.attributes['name']}.h")
-
-        generate_file(
-            str(export_folder / "layers" / f"{self.attributes['name']}.h"),
-            str(ROOT / "templates" / "configuration" / "pooling_config.jinja"),
-            pool_type="Average",
-            activation="Linear",
-            **self.attributes)
-
-        return list_configs
-
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            str(ROOT / "templates" / "kernel_forward" / "pooling_forward.jinja"),
-            **self.attributes
-        ))
-        return list_actions
+        self.config_template = str(ROOT / "templates" / "configuration" / "pooling_config.jinja")
+        self.forward_template = str(ROOT / "templates" / "kernel_forward" / "pooling_forward.jinja")
+        self.include_list = []
+        self.kernels_to_copy = [
+            str(ROOT / "kernels" / "pooling.hpp"),
+            str(ROOT / "kernels" / "activation.hpp"),
+        ]
 
 
 @operator_register("FC")
-class FcCPP(ExportNode):
+class FcCPP(ExportNodeCpp):
     def __init__(self, node):
         super().__init__(node)
-
-    def export(self, export_folder:Path, list_configs:list):
-
-        copyfile(str(ROOT / "kernels" / "fullyconnected.hpp"),
-                 str(export_folder / "include" / "kernels"))
-        copyfile(str(ROOT / "kernels" / "macs.hpp"),
-                 str(export_folder / "include" / "kernels"))
-        copyfile(str(ROOT / "kernels" / "activation.hpp"),
-                 str(export_folder / "include" / "kernels"))
-
-        # Add to config list the include of configurations
-        list_configs.append("kernels/fullyconnected.hpp")
-        list_configs.append(f"layers/{self.attributes['name']}.h")
-
-        # Export configuration file
-        generate_file(
-            str(export_folder / "layers" / f"{self.attributes['name']}.h"),
-            str(ROOT / "templates" / "configuration" / "fullyconnected_config.jinja"),
-            activation="Linear",
-            rescaling="NoScaling",
-            **self.attributes)
-
-        return list_configs
-
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            str(ROOT / "templates" / "kernel_forward" / "fullyconnected_forward.jinja"),
-            **self.attributes
-        ))
-        return list_actions
-
+        self.attributes["activation"] = "Linear"
+        self.attributes["rescaling"] = "NoScaling"
+        self.config_template = str(ROOT / "templates" / "configuration" / "fullyconnected_config.jinja")
+        self.forward_template = str(ROOT / "templates" / "kernel_forward" / "fullyconnected_forward.jinja")
+        self.include_list = []
+        self.kernels_to_copy = [
+            str(ROOT / "kernels" / "fullyconnected.hpp"),
+            str(ROOT / "kernels" / "macs.hpp"),
+            str(ROOT / "kernels" / "activation.hpp"),
+        ]