Если вы поместите это в некоторый контекст, третий способ может быть законным при условии, что второй параметр по умолчанию был задан ранее.
template <class T, class U = double>
struct X;
template <class T = int, class U> //here
struct X {};
int main()
{
X<> x;
X<float> y;
X<char, char> z;
}