模板函数不能直接传递给 std::transform

sko*_*bls 4 c++ templates

给定一个复数向量,我想获得它们的绝对值:

std::vector<std::complex<double>> in; // filling omitted
std::vector<double> out(in.size());
std::transform(in.begin(), in.end(), out.begin(),
                 &std::abs<std::complex<double>> // (1)
//                 [](std::complex<double> z){ return std::abs(z); } // (2)
               );

Run Code Online (Sandbox Code Playgroud)

根据我的理解,第 (1) 行和第 (2) 行应该具有相同的效果。

然而,虽然第 (2) 行编译正确,但第 (1) 行会产生错误:

../../../include/c++/12/bits/stl_algo.h:4263:31: error: cannot convert 'std::complex<double>' to 'double' in assignment
 4263 |         *__result = __unary_op(*__first);
      |                     ~~~~~~~~~~^~~~~~~~~~
      |                               |
      |                               std::complex<double>
Run Code Online (Sandbox Code Playgroud)

为什么我会收到此错误?为什么这里需要匿名函数?

for*_*818 8

的模板参数是用于表示 的std::abs<T>(std::complex<T>)类型。您正在实例化它返回 a但您想要的。Tstd::complex<T>std::abs<std::complex<double>>std::complex<double>std::abs<double>(const std::complex&)

有关详细信息,请参阅https://en.cppreference.com/w/cpp/numeric/complex/abshttps://en.cppreference.com/w/cpp/numeric/complex

通过选择函数指针std::abs<double>将不起作用,因为std::abs已重载并且获取其地址需要通过 a 选择正确的重载static_cast。此外,标准函数可能无法获取其地址,除非它们是显式可寻址函数。使用 lambda 显然是更简单的选择。