std::vector<std::complex<float> > c;
std::vector<float> d;
std::transform(c.begin(), c.end(), d.begin(), std::real<float>);
Why couldn't the compiler resolve the address from the overloaded function real<float>
?
Which overloaded functions does the compiler mean?
Your library implementation has provided additional overloads for std::real<float>
.
26.4.9 Additional overloads [cmplx.over]
1 The following function templates shall have additional overloads:
arg norm conj proj imag real
- 2 The additional overloads shall be sufficient to ensure:
- If the argument has type
long double
, then it is effectively cast tocomplex<long double>
.- Otherwise, if the argument has type
double
or an integer type, then it is effectively cast tocomplex<double>
.- Otherwise, if the argument has type
float
, then it is effectively cast tocomplex<float>
.[...]
You could just use a range based for ...
for (auto v : c) d.push_back(real(v));
... or pack the call to real
into a functor or another function ...
struct my_caller {
template <typename T> T operator() (std::complex<T> const &c) {
return real(c);
}
};
... or use the member function ...
std::transform(c.begin(), c.end(), d.begin(), [](std::complex<T> const &c) {
return c.real();
});
IMPORTANT:
Note that you have to have enough space in the target when using transform
:
std::vector<float> d (c.size());
or use a back inserter:
std::transform(c.begin(), c.end(), back_inserter(d), ...);
Otherwise you are iterating over undefined memory, yielding undefined behaviour.
§26.4.9 states that (amongst others), real
shall have additional overloads, for arguments of type float, double and long double. It seems your libraray implementation made a template for these overloads, maybe like
template <typename T>
T real(T const& t)
{
return std::real(std::complex<T>{t});
}
In addition to the solutions phresnel priovided, you could explicitly tell the compiler which kind of function pointer you mean:
std::transform(c.begin(), c.end(), d.begin(), (float(*)(std::complex<float> const&))std::real<float>);
The compiler then looks for a std::real
that can be converted into a function pointer of the given type and will find the correct one.
I tell you this only for completeness - I consider this explicit cast ugly and would prefer the ranged based for or transform with a lambda.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.