以下代码编译但VC ++ 2015(发布)中的未定义输出和other compilers的运行时错误。
#include <functional>
#include <iostream>
int main()
{
std::function<int(int)> f = [](int x) { return x; };
std::function<const int&(const int& x)> g = f;
std::cout << g( 42 ) << std::endl;
}
为什么允许作业g = f;
?
答案 0 :(得分:5)
考虑重写的等效代码以避免使用lambdas或std::function
:
int f(int x) { return x; }
int const& g(int const& x) { return f(x); }
这是完美的格式良好的代码,然而它会返回一个临时的悬空引用,从而最终导致未定义的行为。由于同样的原因,原始代码是vaid:您可以隐式地将对象转换为相同类型的引用。不幸的是,在这种情况下。
答案 1 :(得分:4)
右值可以绑定到const&
。 const&
可以转换为右值。
检查一下:
int f(int x){return x;}
int const& g(int const& x){ return f(x); }
同样,对g
的调用是合法的,没有错误,但是读取g(42)
的结果是UB - 参考悬挂。
一个好的编译器会看到绑定到临时的引用被返回并发出警告。
function
只是检查是否可以在两者之间转换类型;它没有终身分析。可能它应该,因为我们可以静态地检测到这个错误。