![](/img/trans.png)
[英]std::thread <unresolved overloaded function type> error
[英]Unresolved overloaded function type in std::transfrom
我正在尝试为double
和vector<double>
编写重载 function 。
我刚刚做了以下事情:
constexpr double degrees(double val) { return v * M_1_PI * 180.0; }
std::vector<double> degrees(const std::vector<double>& val)
{
std::vector<double> out;
out.reserve(val.size());
std::transform(val.begin(), val.end(), std::back_inserter(out), degrees);
return out;
}
我希望这是相当简单的,但它不能编译,我无法弄清楚。 编译器无法解析重载degrees
function,一直报错
couldn't deduce template parameter '_UnaryOperation'
编辑:用reserve
修复部分,这是一个明显的错误。
您需要指定应将哪个重载传递给std::transform
。 例如
std::vector<double> degrees(const std::vector<double>& val) {
std::vector<double> out;
out.reserve(val.size());
std::transform(val.begin(), val.end(), std::back_inserter(out), static_cast<double(*)(double)>(degrees));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return out;
}
顺便说一句: std::vector<double> out(val.size());
out
构造为包含值为0.0
的val.size()
元素。 我想这不是你想要的。 默认初始化和reserve
就可以了。
主要有两个问题
有两个函数重载编译器无法自动选择它,使用哪一个。 因此,您需要明确指定将哪一个传递给std::transform
。
std::vector<double> out(val.size());
将创建一个大小val.size()
的 double 向量,所有元素都将以0.0
启动。 std::back_inserter(out)
然后在这些之后添加元素。 据推测,您不希望在实际元素之前在out
向量中有val.size()
数量为0.0
s。 对于不需要的真实位置,您需要一个std::vector::reserve
。
That being said, I would suggest having a lambda function instead of a free function, which has the advantage of having the implementation of the function right into the place where it is called:
std::vector<double> degrees(const std::vector<double>& val)
{
std::vector<double> out;
out.reserve(val.size()); // reserve some memory
std::transform(val.begin(), val.end(), std::back_inserter(out),
[](double ele) {return ele * M_1_PI * 180.0; }
);
return out;
}
你不能传递一个重载集,但你可以传递一个带有重载调用运算符的函子:
struct degrees {
constexpr double operator()(double val) {return val * 0.3 * 180.0;}
std::vector<double> operator()(const std::vector<double>& val) {
std::vector<double> out(val.size());
std::transform(val.begin(), val.end(), std::back_inserter(out), degrees{});
return out;
}
};
我不想相信提问者不知道他们定义了两个同名的函数degrees
,所以我会给我的答案另一种阴影。
怎么可能,在这个电话里
std::transform(val.begin(), val.end(), std::back_inserter(out), degrees);
那个degrees
不知道? 我的意思是, std::transform
应该尝试对val
中的每个元素应用degrees
,并且由于这些元素中的每一个都是double
,因此 transform 应该利用第一个重载,即采用double
的重载不是很明显吗?
然而,尽管这种动机可能令人信服,但它需要编译器将决定应该调用什么degrees
的决定延迟到实际调用的那一刻,即不是在std::transform
的调用站点,而是在std::transform
(特别是在 cppreference 文档页面上的这个可能的实现中评估表达式unary_op(*first1++)
时)。
这根本不可能,因为规则是编译器必须在 function 的调用站点知道它的 arguments 是什么。 参考这个例子,在std::transform
的调用点,编译器不知道需要哪个degree
的重载。
一种解决方法是在 function object 中使用重载的operator()
包装degrees
,如463035818_is_not_a_number所建议的那样; 这样做, object degrees
将在std::transform
调用站点知道,并且仅在std::transform
内部,在对象的operator()
的调用站点,编译器必须在operator()
的重载之间进行选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.