[英]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.