【问题标题】:Assigning std::function<int(int)> to std::function<const int&(const int& x)>将 std::function<int(int)> 分配给 std::function<const int&(const int& x)>
【发布时间】:2023-04-08 04:59:01
【问题描述】:

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

【问题讨论】:

标签: c++ c++11


【解决方案1】:

考虑重写等效代码以避免 lambda 或 std::function

int f(int x) { return x; } 
int const& g(int const& x) { return f(x); } 

这是完全格式良好的代码,但仍会返回对临时对象的悬空引用,因此最终会导致未定义的行为。出于同样的原因,原始代码无效:您可以将对象隐式转换为相同类型的引用。不幸的是,在这种情况下。

【讨论】:

【解决方案2】:

右值可以绑定到const&amp;const&amp; 可以转换为右值。

检查一下:

int f(int x){return x;}
int const& g(int const& x){ return f(x); }

同样,对g 的调用是合法的,没有错误,但读取g(42) 的结果是UB——引用悬空。

一个好的编译器会看到绑定到临时的引用被返回并发出警告。

function 只是检查类型之间是否可以转换;它没有生命周期分析。可能应该,因为我们可以静态检测到这个错误。

【讨论】:

    猜你喜欢
    • 2013-10-15
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 2010-11-11
    相关资源
    最近更新 更多