The nearest thing i could achieve is this: import macros {.emit: """/*TYPESECTION*/ #include <tuple> #include <utility> template <typename... Types> struct TTuple : std::tuple<Types...> { }; """.} type TTuple1[T] {.importcpp:"TTuple<'*0>".} = object TTuple2[T1, T2] {.importcpp:"TTuple<'*0, '*1>".} = object macro TTuple(types: varargs[untyped]): untyped = result = nnkBracketExpr.newTree newIdentNode("TTuple" & $len(types)) for t in types: result.add newIdentNode($t) var x1 : TTuple(int) discard x1 var x2 : TTuple(int, float) discard x2 Run
But accessing by index needs some work, tried adding these: proc `[]=`[T](this: var TTuple1[T], idx: int, value: T) {.importcpp:"std::get<#>(#) = #;".} proc `[]`[T](this: var TTuple1[T], idx: int): T {.importcpp:"std::get<#>(#)".} Run but unfortunately there is no way to substitute arguments to importcpp by positional index when using #