我正在尝试设计一个像这样的简单函数:
void draw(Callback callback)
{
Drawing drawing("name");
callback(drawing);
std::cout << drawing.name() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
wheredrawing应该作为引用传递给回调,以便调用者可以像这样修改它:
draw([](auto& drawing) {
drawing.set_name("another name");
});
Run Code Online (Sandbox Code Playgroud)
现在这可以工作了,因为我将回调参数显式键入为auto&(或Drawing&)。但是,当我仅将参数键入为auto( 或Drawing) 时,代码也会编译,但不再按预期工作。该drawing实例是复制的,而不是通过引用传递的。
当 lambda 参数未显式键入为引用时,我希望代码不再编译。
我尝试过以下方法:
using Callback = std::function<void(Drawing&)>;:drawing当未明确键入 as 时不会被修改auto&。template<typename T> concept Callback = std::is_invocable<void, T, Drawing&>;: 和上面一样。using Callback = void (*)(Drawing&);:这确实有效,但我失去了使用捕获的能力。那么我该如何正确输入 Callback 以便只有Drawing&lambda 才是有效的参数呢?
给出以下代码示例:
class Value { }
Value? value = null;
if (value is not null)
{
Value value2 = value;
}
Run Code Online (Sandbox Code Playgroud)
int? value = null;
if (value is not null)
{
int value2 = value; // CS0266: Cannot implicitly convert type 'int?' to 'int'.
}
Run Code Online (Sandbox Code Playgroud)
我知道这个问题与引用类型与值类型有关。
但是,在这两种情况下,我都检查是否value为 null,那么为什么编译器不能理解第二个示例中 if 块内的值永远不应该为 null?
我可以通过使用来解决这个问题value.Value,但这似乎违反直觉。
如有帮助,将不胜感激。