#include <functional>
void toggleOk(bool& b){ b = !b; }
void toggleBroken(bool b){ b = !b; }
void toggleInt(int i) { i = !i; }
void tooManyParams(boolb, int i){ i = ! b; }
int main()
{
typedef std::function<void(bool&)> CallbackType。
typedef std::function<void(bool) > WrongCallbackType。
CallbackType cb1 = [](bool b) { b = !b; }; // should throw error - missing reference[/span
CallbackType cb2 = toggleOk; // Ok。
CallbackType cb3 = toggleBroken; // Should throw error - missing reference。
CallbackType cb4 = toggleInt; //應該拋出錯誤--整數而不是bool。
WrongCallbackType cb5 = toggleBroken; // Ok。
CallbackType cb6 = cb5; //型別檢查甚至沒有在std::函式之間應用。
CallbackType cb7 = tooManyParams; //只有這條陳述句拋出錯誤。
return 0。
}
考慮到上面的例子,它正在創建一堆回呼,這些回呼有reference到bool作為引數。除了最后一個回呼 cb7,這段代碼可以正常編譯和運行,盡管大多數存盤在回呼物件中的函式與引數的reference或type不匹配。
我曾在 VS19/C 20 中遇到過這種行為,當時 lambda 存盤在 std::function 中,但是我在 Windows 的兩個不同的 G 編譯器中嘗試了這個例子,啟用了額外的診斷程式,并使用了 C 17/C 2a,但沒有一個報告說有警告。
我的問題是 - 這是一個預期的行為還是一個錯誤?為什么?
uj5u.com熱心網友回復:
是的,這是從std::function
std::function使用型別擦除機制來翹起幾乎所有種類的可呼叫物件,并且引數化為非const、非ref的非易失性引數和可呼叫物件的回傳型別。
你需要使用平面型別的函式指標來獲得代碼中的預期錯誤
你需要使用平面型別的函式指標來獲得代碼中的預期錯誤
void toggleOk(bool& b) { b = ! b; }
void toggleBroken(bool b)void toggleInt(int i) {i = !i; }
void tooManyParams(boolb, int i){ i = ! b; }
int main()
{
// typedef std::function<void(bool&)> CallbackType;/span>
// typedef std::function<void(bool)> WrongCallbackType;。
using CallbackType = void(*)(bool& ) 。
using WrongCallbackType = void(*)(bool)。
CallbackType cb1 = [](bool b) { b = !b; }; //錯誤
CallbackType cb2 = toggleOk; // Ok
CallbackType cb3 = toggleBroken; //error
CallbackType cb4 = toggleInt; //錯誤
WrongCallbackType cb5 = toggleBroken; // Ok
CallbackType cb6 = cb5; //錯誤
return 0;
}
現在在上面的CallbackType和WrongCallbackType是不同的型別,并將產生你預期的錯誤。
然而,你只能在lambda的情況下使用函式指標型別(如上圖所示),只有在它是無狀態(不捕獲任何東西)的情況下。
。轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/314159.html
標籤:
下一篇:什么是物體類?
