我撰寫了以下函式,它在遍歷 2d 向量時隱藏回圈:
template<typename ElementType>
void iterateOver2DVector(std::vector<std::vector<ElementType>> & vec,
std::function<void(ElementType & element)> function)
{
for(auto & row : vec)
{
for(auto & element : row)
{
function(element);
}
}
}
但我得到錯誤:
'function': no matching overloaded function found
和
'declaration' : could not deduce template argument for 'type' from 'type'
當它與這樣的 lambda 一起使用時:
iterateOver2DVector(graph, [](Node & node) { node.update(); } );
有人知道我做錯了什么嗎?
uj5u.com熱心網友回復:
該呼叫將嘗試ElementType從第一個和第二個引數/引數對中進行推斷。
第二對將失敗,因為函式的第二個引數不是 a std::function,而是閉包型別。
如果一對失敗,那么整個推導失敗,即使另一對ElementType正確地推匯出模板引數。
您的函式不需要ElementType從第二個引數/引數對中進行推斷,因此您可以將其設為非推斷背景關系,這樣就不會嘗試對其進行推斷。
一種常見的方法是使用std::type_identity_t:
template<typename ElementType>
void iterateOver2DVector(std::vector<std::vector<ElementType>> & vec,
std::type_identity_t<std::function<void(ElementType & element)>> function)
std::type_identity_t<T>是一個別名,std::type_identity<T>::type它是 的別名T,但是由于T現在型別是 a 的左側,::因此它處于非推導背景關系中。
std::type_identity_t僅從 C 20 開始可用,但可以在以前的 C 版本中輕松定義:
template<typename T> struct type_identity { using type = T; };
template<typename T> using type_identity_t = typename type_identity<T>::type;
但是,在這種情況下,std::function無論如何只是不必要的開銷。只需直接接受閉包型別,而不是std::function:
template<typename ElementType, typename F>
void iterateOver2DVector(std::vector<std::vector<ElementType>> & vec,
F function)
Astd::function僅在您打算存盤可呼叫而不依賴于其特定型別(例如在類成員中)時才有用,即使在這種情況下,std::function也可以在分配給成員時完成轉換。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/452866.html
