C++ C++;lambda不';t推断函数重载
我定义了这样一个类:C++ C++;lambda不';t推断函数重载,c++,lambda,overloading,C++,Lambda,Overloading,我定义了这样一个类: class foo { public: // I define const and non-const versions of the 'visit' function // nb. the lambda is passed by reference virtual void visitWith(std::function<void(foo&)>&); virtual void visitWith(std::function<
class foo {
public:
// I define const and non-const versions of the 'visit' function
// nb. the lambda is passed by reference
virtual void visitWith(std::function<void(foo&)>&);
virtual void visitWith(std::function<void(const foo&)>&) const;
};
foo f;
f.visitWith([&](const foo&) {
// Do something here
});
foo f;
f.visitWith( (std::function<void(const foo&)>) [&](const foo&) {
// Do something here
});
class foo {
public:
// Use typedefs so that all the code that comes after these two functions is neater
typedef std::function<void(Branch&)>visitor;
typedef std::function<void(const Branch&)>const_visitor;
virtual void visitWith(const visitor&);
virtual void visitWith(const const_visitor&) const;
// This is to thunk the third case that can happen when you start
// a const visit from a non-const foo.
void visitWith(const const_visitor& v) {
static_cast<const foo*>(this)->visitWith(v); // Add const-ness
}
};
我得到编译器错误。编译器不知道该做什么
我可以通过添加这样的类型转换使其工作:
class foo {
public:
// I define const and non-const versions of the 'visit' function
// nb. the lambda is passed by reference
virtual void visitWith(std::function<void(foo&)>&);
virtual void visitWith(std::function<void(const foo&)>&) const;
};
foo f;
f.visitWith([&](const foo&) {
// Do something here
});
foo f;
f.visitWith( (std::function<void(const foo&)>) [&](const foo&) {
// Do something here
});
class foo {
public:
// Use typedefs so that all the code that comes after these two functions is neater
typedef std::function<void(Branch&)>visitor;
typedef std::function<void(const Branch&)>const_visitor;
virtual void visitWith(const visitor&);
virtual void visitWith(const const_visitor&) const;
// This is to thunk the third case that can happen when you start
// a const visit from a non-const foo.
void visitWith(const const_visitor& v) {
static_cast<const foo*>(this)->visitWith(v); // Add const-ness
}
};
foof;
f、 visitWith((std::function)[&](constfoo&){
//在这里做点什么
});
但那太可怕了
我怎样才能让它干净利落地工作呢
编辑:
这可能是VisualC++中的一个问题,它拒绝编译这里给出的代码:
我尝试编译时的VC++输出是:<2> Edt2:不,Visual C++是正确的,代码是模糊的。请参阅下面的我的解决方案…lambda是编译器生成的类型,它不是
std::function
的实例,但可以分配给一个实例
您的visitWith()
方法通过非常量引用获取std::function
,这意味着它需要一个预先存在的std::function
对象,例如:
std::function func=[&](const foo&){
//在这里做点什么
};
福福;
f、 visitWith(func);
将lambda直接传递给visitWith()
需要编译器创建一个临时std::function
对象,但非常量引用不能绑定到临时对象。这就是原始代码无法编译的原因
对于您正在尝试的内容,您必须通过值或常量引用传递std::function
:
class-foo{
公众:
void visitWith(std::function);
void visitWith(std::function)const;
};
class-foo{
公众:
void visitWith(const std::function&);
void visitWith(const std::function&)const;
};
我向微软报告了这个“错误”,并得到了回复,如下所示:
短版本:VisualC++是正确处理的,IDENON是错误的。 最后,我通过向foo添加第三个重载来解决这个问题,该重载可以向对象添加常量,如下所示:
class foo {
public:
// I define const and non-const versions of the 'visit' function
// nb. the lambda is passed by reference
virtual void visitWith(std::function<void(foo&)>&);
virtual void visitWith(std::function<void(const foo&)>&) const;
};
foo f;
f.visitWith([&](const foo&) {
// Do something here
});
foo f;
f.visitWith( (std::function<void(const foo&)>) [&](const foo&) {
// Do something here
});
class foo {
public:
// Use typedefs so that all the code that comes after these two functions is neater
typedef std::function<void(Branch&)>visitor;
typedef std::function<void(const Branch&)>const_visitor;
virtual void visitWith(const visitor&);
virtual void visitWith(const const_visitor&) const;
// This is to thunk the third case that can happen when you start
// a const visit from a non-const foo.
void visitWith(const const_visitor& v) {
static_cast<const foo*>(this)->visitWith(v); // Add const-ness
}
};
class-foo{
公众:
//使用typedefs以便这两个函数后面的所有代码都更整洁
typedef std::functionvisitor;
typedef std::functionconst_访问者;
虚拟无效访问(const visitor&);
虚拟无效访问(const const_visitor&)const;
//这是第三种情况,当你开始时可能会发生
//来自非康斯特福的康斯特访问。
无效访问(const const_访问者&v){
静态(this)->visitWith(v);//添加常量
}
};
现在代码开始工作,例如:
foo f;
f.visitWith([](const foo& f) {
std::cout << "visited a const foo!" << std::endl;
});
foof;
f、 visitWith([])(const foo&f){
std::我认为通过值传递的lambda会在每次函数调用时复制该对象,这可能会很昂贵吗?(取决于lambda捕获的内容),或者lambda更像是廉价的复制函数指针吗?通过值传递的lambda确实可以进行复制,是的。可以将lambda视为一个匿名结构,并实现了运算符()
。但是您的visitWith
并没有获取/传递lambda本身(visitWith
必须使用模板参数才能做到这一点)这是一个关于lambda的代码< St::Stult。这可能是VisualC++中的一个问题,它拒绝编译下面所示的代码,即使它在该网站上编译并运行:Edg:在初始问题^ ^中添加了编译器错误的图像。w lambda已通过。这与您的原始代码没有什么不同,只是使用了typedef,这是不必要的。请参阅我刚才添加到答案中的演示链接,其中显示了我的示例的工作情况。