А смысл писать шаблон? Перегрузной гораздо правильней получается.
Код:
// шаблон
template<typename X> std::vector<X> polynom2_roots(X a X b, X c)
{
std::vector<X> result;
X det = b*b - 4*a*c;
if (X()<=det)
{
det = std::sqrt(det);
result.push_back((det-b)/(a*2));
if (X()<det)
{
result.push_back((-det-b)/(a*2));
}
}
return result;
}
template<typename X> std::vector<std::complex<X> > polynom2_roots(std::complex<X> a std::complex<X> b, std::complex<X> c)
{
std::vector<std::complex<X> > result;
X det = std::sqrt(b*b - 4*a*c);
result.push_back((-b+det)/(a*2));
if (X()!=det)
{
result.push_back((-det-b)/(a*2));
}
return result;
}
// При компиляции могут возникать неопределённости при выборе параметров шаблона.
// Если убрать все template<...> и заменить X на double, мне кажется получится лучше.
// Если задача стоит математическая (не сугубо прикладная), то использование std::complex<double>
// просто идеально для машин P-4
Если не нужно делать выбор более подходящего алгоритма для решения линейной и квадратичной задачи, то можно задать параметры по умолчанию и поменять порядок аргументов:
Код:
template<...> ... polynom2_roots(X c, X b, X a=X());
Для выбора алгоритма, внутри можно добавить:
Код:
if (a==X()) // линейное уравнение
else // квадратичное
Можно сделать так, чтобы выбор алгоритма выполнялся статически (тогда если вдруг по ходу выполнения программы окажется что a=0, будет всё равно решаться полное уравнение).
[code]
template<...> ... polynom2_roots(X c, X b, X a); // квадратичное
template<...> ... polynom2_roots(X c, X b); // линейное
[code]