我試圖為double和vector<double>撰寫一個多載函式。
我剛剛做了以下作業:
。
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函式,并且一直在抱怨
couldn't deduce template parameters '_UnaryOperation'
編輯:修復帶有reserve的部分,這是一個明顯的錯誤。
uj5u.com熱心網友回復:
你需要指定哪個多載應該被傳遞給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)>(度))。
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return out;
}
BTW: std::vector<double> out(val.size());將構建out為包含val.size()元素的值0.0。我想這不是你想要的。默認初始化和reserve就可以了。
uj5u.com熱心網友回復:
主要有兩個問題
有兩個函式多載,編譯器不能自動選擇使用哪一個。所以你需要明確指定哪一個要傳遞給std::transform。
std::vector<double> out(val.size());將創建一個大小為val.size()的double向量,所有的元素將被啟動0.0。std::back_inserter(out)然后在這些元素之后添加元素。據推測,你不希望在實際的元素之前,在val.size()向量中出現0.0的數量。你需要一個std::vector::reserve那里,用于不需要的真實位置。
既然如此,我建議用lambda函式來代替自由函式,這樣做的好處是將函式的實作直接放到被呼叫的地方:
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),
[](double ele) {return ele * M_1_PI * 180.0; }; ;return ele * M_1_PI * 180.0; }
);
return out;
}
uj5u.com熱心網友回復:
你不能傳遞一個多載集,但你可以傳遞一個帶有多載呼叫運算子的函式器:
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。
}
};
uj5u.com熱心網友回復:
我不想相信提問者不知道他們在定義兩個名字相同的函式degrees,所以我將給我的答案加上另一個陰影。
在這個呼叫中,怎么可能呢
std::transform(val. begin(), val.end(), std::back_inserter(out), degrees) 。
那個 盡管這個動機可能是令人信服的,但是它將要求編譯器推遲/定義什么 這是不可能的,因為規則規定,編譯器必須在函式的呼叫位置知道它的引數是什么。參照這個例子,在 一種方法是將
標籤: 上一篇:什么是nth_element,它到底是做什么的?以及如何實作它
下一篇:egrep回傳以字串分隔的匹配項
degrees是不知道的?我的意思是,std::transform應該嘗試將degrees應用到val中的每一個元素,由于這些元素都是一個double,所以transform應該使用第一個多載,即接受double的那個多載,這不是很明顯嗎?
degrees應該被呼叫的決定,即不是在std::transform的呼叫位置,而是在std::transform內。
std::transform的呼叫位置,編譯器不知道需要degree的哪個多載。
degrees包裹在一個具有多載operator()的函式物件中,正如463035818_is_not_a_number;這樣做,object degrees將在std::transform呼叫站點被知道,并且只在inside std: :transform,在物件的operator()的呼叫位置,編譯器將不得不在operator()的多載中進行選擇。
