请考虑以下代码:
#include <iostream>
#include <functional>
// passing function object by value
void foo(std::function<int(int, int)> f) {
std::cout << f(3, 7) << std::endl;
}
// passing const function object by reference
void bar(const std::function<int(int, int)> & f) {
std::cout << f(3, 7) << std::endl;
}
// passing non-const function object by reference
void fizz(std::function<int(int, int)> & f) {
std::cout << f(3, 7) << std::endl;
}
int main() {
std::function<int(int, int)> g1 = [] (int x, int y) { return x * y; };
auto g2 = [] (int x, int y) { return x * y; };
foo(g1); // OK
foo(g2); // OK
bar(g1); // OK
bar(g2); // OK
fizz(g1); // OK
// compile error:
// error: invalid initialization of reference of type
// 'std::function<int(int, int)>&' from expression of type
// 'main()::<lambda(int, int)>'
// error: in passing argument 1 of 'void fizz(std::function<int(int, int)>&)'
fizz(g2);
}
Run Code Online (Sandbox Code Playgroud)
有人会向我解释:
(a)为什么会fizz(g2)生成编译错误,而其他结构却没有?似乎我可以通过引用传递一个lambda,如果我在其声明中明确地键入它的类型,但是如果我使用auto关键字则不是,或者如果我将函数参数类型声明为const.
(二)什么做 const的函数参数类型的意思是在这里吗?
(C) 在什么情况下我更愿意通过价值而不是参考(更新:现在一个单独的问题:C++ 11:通过引用或值传递(lambda或其他)函数对象?)?
感谢您的任何见解.
Nic*_*las 10
在你的fizz(g1)情况下,g1已经是一个std::function.因此,不需要隐式转换.所以fizz参数是非const引用g1.
在fizz(g2),g2是不是一个std::function.因此,编译器必须执行隐式转换.而隐式转换返回一个临时的.
临时对象不能绑定到非const引用; 它们只能绑定到const引用或值.因此编译错误.
函数参数类型中的const是什么意思?
您只能调用const该对象的成员,您不能将其隐式转换为非const,并且您不能const对其成员执行非操作.
你知道,就像任何其他用途的const.
一般来说,当一个函数通过非const引用获取一个参数时,它会说一些关于它打算用该参数做什么的特别之处.也就是说,你正在处理一个对象,并且它会用它做非常量的东西(即:修改那个对象).这就是为什么temporaries不绑定到非const引用; 这可能是用户的错误,因为临时可能不会更新您传递的原始对象.
除非fizz实际上要修改对象,否则应该通过值或通过它传递它const&.