std::vector<std::complex<float> > c;
std::vector<float> d;
std::transform(c.begin(), c.end(), d.begin(), std::real<float>);
为什么编译器无法解析重载函数real<float>
中的地址?
编译器意味着哪些重载函数?
答案 0 :(得分:5)
您的库实现为std::real<float>
提供了额外的重载。
26.4.9附加重载[cmplx.over]
1以下功能模板应具有额外的重载:
arg norm conj proj imag real
- 2额外的重载应足以确保:
- 如果参数的类型为
long double
,则会将其有效地转换为complex<long double>
。- 否则,如果参数的类型为
double
或整数类型,则它会被有效地转换为complex<double>
。- 否则,如果参数的类型为
float
,则它有效地转换为complex<float>
。[...]
您可以使用基于...的范围
for (auto v : c) d.push_back(real(v));
...或将对real
的调用打包到仿函数或其他函数中......
struct my_caller {
template <typename T> T operator() (std::complex<T> const &c) {
return real(c);
}
};
...或使用会员功能......
std::transform(c.begin(), c.end(), d.begin(), [](std::complex<T> const &c) {
return c.real();
});
重要:
请注意,使用transform
时,您必须在目标中留出足够的空间:
std::vector<float> d (c.size());
或使用后插入器:
std::transform(c.begin(), c.end(), back_inserter(d), ...);
否则,您将迭代未定义的内存,从而产生未定义的行为。
答案 1 :(得分:4)
§26.4.9声明(其中)real
对于float,double和long double类型的参数应该有额外的重载。看来你的libraray实现为这些重载做了一个模板,可能就像
template <typename T>
T real(T const& t)
{
return std::real(std::complex<T>{t});
}
除了phresnel priovided解决方案之外,你可以明确告诉编译器你指的是哪种函数指针:
std::transform(c.begin(), c.end(), d.begin(), (float(*)(std::complex<float> const&))std::real<float>);
然后,编译器会查找可以转换为给定类型的函数指针的std::real
,并找到正确的函数指针。
我告诉你这只是为了完整 - 我认为这个显式转换丑陋,并且更喜欢基于范围或用lambda转换。