当前位置: 首页 > 知识库问答 >
问题:

为什么C 17中std::函数的运算符()会发生变化?

钱宇
2023-03-14

以下代码在C 14中被认为是非法的,但在C 17中是合法的:

#include <functional>

int main()
{
    int x = 1729;
    std::function<void (int&)> f(
        [](int& r) { return ++r; });
    f(x);
}

不要费心测试它,你会得到不一致的结果,很难确定这是一个错误还是故意的行为。但是,比较两个草案(N4140 vs N4527,都可以在github.com/cplusplus/draft上找到),[func.wrap.func.inv]有一个显著的区别。第2段:

返回:如果R为空,则无,否则返回值INVOKE(f, std::forward(args)..., R)。

以上内容已在草稿之间删除。这意味着lambda的返回值现在被悄悄地丢弃。这似乎是一个错误的特征。谁能解释一下原因吗?

共有1个答案

仰雅昶
2023-03-14

标准中关于std::function有一个荒谬的缺陷

void foo(){}std::function

一些编译器采用了使std::function

其他编译器只是忽略了void返回类型案例中的糟糕措辞。

缺陷基本上是调用表达式的返回类型必须是隐式可转换的——到std::function的签名的返回类型(有关更多详细信息,请参阅上面的链接)。并且在标准下,ulul不能隐式转换为ulul2

所以缺陷被解决了<代码>标准::函数

std::function从来都不需要参数或返回值的精确匹配,只需要兼容性。如果传入参数可以隐式地从签名参数转换而来,并且返回类型可以隐式地转换为返回类型,那就很好了。

int(int)类型的函数

1基本上,任何使operator()呼叫合法的行为都是不允许的。你可以创建它,可以销毁它,可以测试它(知道它是空的)。你不能给它一个函数,甚至不能给它一个与签名完全匹配的函数,也不能给它一个函数对象或lambda。荒唐的

2要在标准下将ulul隐含地转换为ulul,它要求语句ulul x=blah;,其中blah是ulul类型的表达式,是有效的;该语句无效,因为您不能创建ulul类型的变量。

 类似资料:
  • 我使用的是我的代码中有两个可观察的对象 观察值不是来自请求,而是来自 我需要根据这个逻辑将序列组合/转换成一个单一的可观察值: 如果序列,或,-需要返回新的可观察的否则需要返回 我试图使用来实现: 但问题是我的

  • 在阅读std::unordered_map使用的std::hash示例时,我注意到,{}正在访问operator()函数。 http://en.cppreference.com/w/cpp/utility/hash 这里{}的用法代表什么?

  • 为什么运算符只应该是4个字节却生成12个字节?当我引用变量时,这只是引用数组第一个索引的内存地址。实际上,我打印了第一个索引的内存地址,并将其与进行了比较,它们产生了相同的内存地址结果,这证实了它们都引用了数组的第一个索引,但是“array”产生了12个字节,而产生了4个字节。

  • 我正在制作我的程序,为JavaSE的学校作业扔一个骰子(如骰子)。用户可以将一个字符作为标准输入,因此用户选择的字符将代表骰子的眼睛。有时当我打印结果时,它会显示一个完全不同的字符。 输出此程序将生成正确的结果。但偶尔输入的字符(代表模具的眼睛)会转换为数字。 在以下情况下,程序应打印9个“@”字符。相反,它在第一行打印192。(我知道骰子有6只眼睛,但我在无意中打印了9只眼睛时遇到了这个奇怪的输

  • 问题内容: 该功能运行什么?它只会运行吗? 问题答案: setState()将按以下顺序运行函数: 如果您的组件正在接收道具,它将使用上述功能运行该功能。

  • 问题内容: 在我的项目中,我的一个同事非常反对使用运算符,因为它“会产生大量开销”,这是什么原因呢?是真的吗 还有另一种方法可以检查对象的类型而不使用它? 因为我发现它在某些情况下非常有用。 问题答案: 确实产生一些开销,再加上后续的转换。使用最新版本的Java,开销已减少。但是无论如何,这都是微优化-也就是说,在一般情况下,您不必为此担心。 真正的反对意见是,在许多情况下,有更好的OOP方法可以