【发布时间】:2021-08-29 08:16:44
【问题描述】:
#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;
}
考虑上面的例子,它创建了一组以bool 为参数的reference 回调。除了最后一个回调cb7,这段代码可以编译和运行得很好,即使大多数存储在回调对象中的函数与reference或type不匹配参数。
我在 VS19/C++20 中遇到了这种行为,lambda 存储在 std::function 中,但是我已经使用两个不同的 Windows G++ 编译器尝试了这个示例,启用了额外的诊断功能并使用了 C++ 17/C++2a 甚至没有报告警告。
我的问题是 - 这是预期的行为还是错误?为什么?
【问题讨论】:
-
检查大致是:
bool b{}; toggleInt(b);,并且可以编译(tooManyParams除外)。 -
我看到的方式是你创建一个 std::function 传递一个 ref 参数,然后调用一个没有 ref 的底层函数。这很好,裁判不会改变,一切都很好。如果您调用 cb1、cb2 等,我会在运行时检查。行为完全符合预期。
标签: c++ function c++11 c++17 std-function