You could define two function template overloads (when it comes to function templates, overloading is usually preferable to specialization) called compute_norm()
, one accepting std::complex
and one accepting unconstrained types. The unconstrained template would invoke operator *
, while the constrained template would invoke std::norm()
.
#include <complex>
template<typename T>
double compute_norm(T t)
{ return t * t; }
template<typename T>
double compute_norm(std::complex<T> const& t)
{ return std::norm(t); }
Then, your generic code that can work both with a double
and with a complex<double>
would call compute_norm()
:
#include <iostream>
template<typename T>
void foo(T&& t)
{
// ...
double n = compute_norm(std::forward<T>(t));
std::cout << n << std::endl;
// ...
}
For instance, the following program:
int main()
{
double a(2.0);
foo(a);
std::complex<double> c(2.0, 3.0);
foo(c);
}
Will output:
4
13
Here is a live example.