use std::is_same and std::true_type to do tag dispatch