diff --git a/include/aidge/utils/StaticAttributes.hpp b/include/aidge/utils/StaticAttributes.hpp
index b67f69ae7afc2c22f3b424812ec994b10974b668..50ed0895e82bb468dee57264534f0ec3a486a815 100644
--- a/include/aidge/utils/StaticAttributes.hpp
+++ b/include/aidge/utils/StaticAttributes.hpp
@@ -22,8 +22,8 @@
 
 namespace Aidge {
 /**
- * @brief This class is designed to handle static attributes (i.e. known at compile-time) 
- * with named accessors, with minimal overhead (the name strings are not stored in each object 
+ * @brief This class is designed to handle static attributes (i.e. known at compile-time)
+ * with named accessors, with minimal overhead (the name strings are not stored in each object
  * instance and it remains possible to access attribute without overhead at compile-time).
 */
 template <class ATTRS_ENUM, class ...T>
@@ -97,6 +97,17 @@ public:
         AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute \"%s\" not found", name);
     }
 
+    template <typename R>
+    const R& getAttr(const char* name) const {
+        for (std::size_t i = 0; i < size(EnumStrings<ATTRS_ENUM>::data); ++i) {
+            if (strcmp(EnumStrings<ATTRS_ENUM>::data[i], name) == 0) {
+                return getAttr<R>(i);
+            }
+        }
+
+        AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute \"%s\" not found", name);
+    }
+
     template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value>
     typename std::enable_if<(SIZE > 0), R&>::type getAttr(std::size_t i) {
         if (i == SIZE-1) {
@@ -117,6 +128,26 @@ public:
         AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute not found");
     }
 
+    template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value>
+    typename std::enable_if<(SIZE > 0), const R&>::type getAttr(std::size_t i) const {
+        if (i == SIZE-1) {
+            if (std::is_same<R, typename std::tuple_element<SIZE-1,std::tuple<T...>>::type>::value) {
+                return reinterpret_cast<const R&>(std::get<SIZE-1>(mAttrs));
+            }
+            else {
+                AIDGE_THROW_OR_ABORT(std::runtime_error, "wrong type for attribute with index %lu", i);
+            }
+        }
+        else {
+            return getAttr<R, SIZE-1>(i);
+        }
+    }
+
+    template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value>
+    [[noreturn]] typename std::enable_if<(SIZE == 0), const R&>::type getAttr(std::size_t /*i*/) const {
+        AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute not found");
+    }
+
     template <std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value>
     constexpr typename std::enable_if<(SIZE > 0), const std::type_info&>::type getAttrType(std::size_t i) const {
         if (i == SIZE-1) {