implementation using templates