use std::declval instead of T()