factory using type traits