将std :: function <int(int)>赋值给std :: function <const int&(const =“”int&=“”x)=“”>

时间:2016-04-01 14:52:16

标签: c++ c++11

以下代码编译但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;

2 个答案:

答案 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只是检查是否可以在两者之间转换类型;它没有终身分析。可能它应该,因为我们可以静态地检测到这个错误。