doo*_*sta 4 c++ function c++11 std-function c++17
#include <functional>
void toggleOk(bool& b) { b = !b; }
void toggleBroken(bool b) { b = !b; }
void toggleInt(int i) { i = !i; }
void tooManyParams(bool b, 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
CallbackType cb2 = toggleOk; // Ok
CallbackType cb3 = toggleBroken; // Should throw error - missing reference
CallbackType cb4 = toggleInt; // Should throw error - integer instead of bool
WrongCallbackType cb5 = toggleBroken; // Ok
CallbackType cb6 = cb5; // Type checking not even applying between std::functions
CallbackType cb7 = tooManyParams; // Only this statement throws error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
考虑上面的例子中,其被创建一束具有回调的参考来bool作为参数。除了最后一个 callback cb7,这段代码可以很好地编译和运行,即使存储在回调对象中的大多数函数与参数的引用或类型不匹配。
我遇到这种行为与VS19 / C ++ 20与存储在拉姆达std::function,但是我已经试过了Windows中两个截然不同的G ++编译器这个例子中,额外的诊断启用和C ++ 17 / C ++ 2A甚至没有人报告警告。
我的问题是 - 这是预期的行为还是错误?为什么?
是的,这是从定义的行为 std::function
的std::function使用类型擦除机制到经纱几乎所有类型的可调用的对象,以及参数化以非const,非参考非易失性参数和调用的返回类型。
您需要使用平面类型函数指针来获取代码中的预期错误
void toggleOk(bool& b) { b = !b; }
void toggleBroken(bool b) { b = !b; }
void toggleInt(int i) { i = !i; }
void tooManyParams(bool b, int i) { i = !b; }
int main()
{
// typedef std::function<void(bool&)> CallbackType;
// typedef std::function<void(bool)> WrongCallbackType;
using CallbackType = void(*)(bool&);
using WrongCallbackType = void(*)(bool);
CallbackType cb1 = [](bool b) { b = !b; }; // error
CallbackType cb2 = toggleOk; // Ok
CallbackType cb3 = toggleBroken; // error
CallbackType cb4 = toggleInt; // error
WrongCallbackType cb5 = toggleBroken; // Ok
CallbackType cb6 = cb5; // error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在在上面CallbackType和WrongCallbackType是不同的类型,并且会产生您预期的错误。
但是,您只能在 lambda 的情况下使用函数指针类型(如上所示),前提是它是无状态的(不捕获任何内容)。
| 归档时间: |
|
| 查看次数: |
87 次 |
| 最近记录: |