c++ - g++ 为 transform() 的参数生成错误
问题描述
g++ 会为此代码生成错误。我必须更改std::sin
为(double (*)(double))std::sin
. 为什么?
#include <iostream>
#include <list>
#include <algorithm>
#include <cmath>
int main(int argc, char *argv[])
{
std::list<double> radians = {0.0, 3.14/2, 3.14};
std::list<double> sines(radians.size());
std::transform(radians.begin(), radians.end(), sines.begin(), std::sin);
for(auto i = radians.begin(), j = sines.begin(); i != radians.end(); i++, j++)
std::cout << "Angle and sine: " << *i << " " << *j << std::endl;
return 0;
}
解决方案
因为std::transform
是函数模板,所以函数对象形参的类型被声明为模板形参,需要从函数实参中推导出来。但是std::sin
有几个重载,没有上下文来确定应该选择哪个重载,然后用来推导模板参数。
您可以使用static_cast
(或您展示的 c-style cast)来指定一个。
static_cast
也可用于通过执行到特定类型的函数到指针转换来消除函数重载的歧义,如std::for_each(files.begin(), files.end(), static_cast<std::ostream&(*)(std::ostream&)>(std::flush));
例如
std::transform(radians.begin(), radians.end(), sines.begin(), static_cast<double(*)(double)>(std::sin));
或者显式指定模板参数以绕过模板参数推导。对于已知的函数参数类型,将执行重载决议以选择适当的重载。
std::transform<std::list<double>::iterator,
std::list<double>::iterator,
double(*)(double)
>(radians.begin(),
radians.end(),
sines.begin(),
std::sin
);
推荐阅读
- javascript - 如何使用 React Ref 和 UseLayoutEffect 调整可滚动列表的大小?
- c++ - 联合成员分配中的 C++ 分段错误
- visual-studio-code - 通过环境模块管理的 HPC 服务器上的 VSCode 远程开发服务器先决条件
- scala - 如何用 ZIO 解释最终的无标签 DSL?
- linux - For循环选择字符串变量的特定部分
- sql - 返回值不存在的所有数据
- c# - 从 JWT 获取自定义声明的值
- python - 根据其他两列的值在 Pandas 中创建一个新列
- docker - .env 文件更改后,dotenv celery docker 容器未立即更新
- angular - 将 CdkOverlay 放在 angular/elements webcomponent 内