从重载函数std :: real <float>解析地址

Vad*_*ets 7 c++ algorithm stl overloading

std::vector<std::complex<float> > c;
std::vector<float> d;
std::transform(c.begin(), c.end(), d.begin(), std::real<float>);
Run Code Online (Sandbox Code Playgroud)

为什么编译器无法解析重载函数的地址real<float>

编译器意味着哪些重载函数?

Seb*_*ach 5

您的库实现为其提供了额外的重载std::real<float>.

为什么超载?

26.4.9附加重载[cmplx.over]

  • 1以下功能模板应具有其他重载:

    arg norm
    conj proj
    imag real
    
    Run Code Online (Sandbox Code Playgroud)
  • 2额外的过载应足以确保:
    1. 如果参数有类型long double,那么它将被有效地转换为complex<long double>.
    2. 否则,如果参数具有类型double或整数类型,则它将被有效地转换为complex<double>.
    3. 否则,如果参数有类型float,那么它将被有效地转换为complex<float>.

[...]

解决问题的方法:

您可以使用基于...的范围

for (auto v : c) d.push_back(real(v));
Run Code Online (Sandbox Code Playgroud)

...或打电话到real仿函数或其他功能......

struct my_caller {
    template <typename T> T operator() (std::complex<T> const &c) {
        return real(c);
    }
};
Run Code Online (Sandbox Code Playgroud)

...或使用会员功能......

std::transform(c.begin(), c.end(), d.begin(), [](std::complex<T> const &c) { 
    return c.real();
});
Run Code Online (Sandbox Code Playgroud)

重要:

请注意,使用时,您必须在目标中有足够的空间transform:

std::vector<float> d (c.size());
Run Code Online (Sandbox Code Playgroud)

或使用后插入器:

std::transform(c.begin(), c.end(), back_inserter(d), ...);
Run Code Online (Sandbox Code Playgroud)

否则,您将迭代未定义的内存,从而产生未定义的行为.