我可以将可调用对象分配给具有不同返回类型的 std::function 吗?

问题描述 投票:0回答:2

我将一个函数存储在

std::function
中。调用这个存储函数时我不关心返回值,所以
std::function
只返回
void

调用存储函数时是否有任何未定义的行为?

以以下示例作为参考,其中函数是返回

int
的 lambda(链接到运行):

#include <iostream>
#include <functional>
std::function<void(void)> f;
int main()
{
    f = []() -> int { std::cout << "Returning int\n";  return 0; };
    f(); // Is this UB in any way?
    return 0;
}

这个问题不仅适用于 lambda,还适用于任何可调用的,例如成员函数、自由函数等。

c++ undefined-behavior std-function
2个回答
9
投票

忽略返回结果是明确允许的。

您正在使用

template< class F > function& operator=( F&& f );
operator=
重载,它有以下要求:

此运算符不参与重载解析,除非对于参数类型

f
和返回类型 Args...R
Callable

哪个是

INVOKE<R>(f, std::declval<ArgTypes>()...)
在未评估的上下文中格式良好。

仅展示操作

INVOKE<R>(f, arg_0, arg_1, arg_2, ..., arg_N)
定义如下:

  • 如果

    R
    (可能符合简历资格)
    void

    • static_cast<void>(INVOKE(f, arg_0, arg_1, arg_2, ..., arg_N)).

即它通过转换为

void

显式丢弃结果

2
投票

这是有效的代码,返回将被简单地丢弃。

但是,很难通过快速检查判断这是有意还是疏忽。

使用

std::ignore
等工具澄清这是您的意图将有助于提高代码的可读性

auto g =  []() -> int { std::cout << "Returning int\n";  return 0; };

f = [&g]() -> void{ std::ignore = g(); };

//use g somewhere else or refactor to eliminate g
© www.soinside.com 2019 - 2024. All rights reserved.