简体   繁体   English

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

[英]resolve address from overloaded function std::real<float>

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> ? 为什么编译器无法解析重载函数real<float>的地址?

Which overloaded functions does the compiler mean? 编译器意味着哪些重载函数?

Your library implementation has provided additional overloads for std::real<float> . 您的库实现为std::real<float>提供了额外的重载。

Why the overloads? 为什么超载?

26.4.9 Additional overloads [cmplx.over] 26.4.9附加重载[cmplx.over]

  • 1 The following function templates shall have additional overloads: 1以下功能模板应具有其他重载:

     arg norm conj proj imag real 
  • 2 The additional overloads shall be sufficient to ensure: 2额外的过载应足以确保:
    1. If the argument has type long double , then it is effectively cast to complex<long double> . 如果参数的类型为long double ,则它有效地转换为complex<long double>
    2. Otherwise, if the argument has type double or an integer type, then it is effectively cast to complex<double> . 否则,如果参数具有double类型或整数类型,则它有效地转换为complex<double>
    3. Otherwise, if the argument has type float , then it is effectively cast to complex<float> . 否则,如果参数的类型为float ,则它有效地转换为complex<float>

[...] [...]

Solutions to problem: 解决问题的方法:

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 ... ...或者将real电话打包成仿函数或其他功能......

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 : 请注意,使用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. §26.4.9规定,对于float,double和long double类型的参数, real应具有额外的重载。 It seems your libraray implementation made a template for these overloads, maybe like 看来你的libraray实现为这些重载做了一个模板,也许就像

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: 除了phresnel priovided解决方案之外,您还可以明确地告诉编译器您指的是哪种函数指针:

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. 然后编译器查找std::real ,它可以转换为给定类型的函数指针,并找到正确的指针。

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. 我告诉你这只是为了完整性 - 我认为这显然是非常丑陋的,并且更喜欢基于lambda的范围或变换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM