【问题标题】:Can tr1::function swallow return values?tr1::function 可以吞下返回值吗?
【发布时间】:2011-10-01 11:44:22
【问题描述】:

boost::function FAQ item 3 专门针对我感兴趣的场景:

为什么会有 void 的变通方法 回报? C++ 允许它们!无效退货 C++ 标准允许,如 在这段代码sn-p中:

void f();
void g() { return f(); }

这是一个有效的用法 boost::function 因为 void 返回 不使用。使用无效返回,我们 会试图编译格式错误的 代码类似:

int f();
void g() { return f(); }

本质上,不使用 void 返回 允许 boost::function 吞下一个 返回值。这与 允许用户分配和调用 函数和函数对象 参数不完全匹配。

不幸的是,这在 VS2008 中不起作用:

int Foo();
std::tr1::function<void()> Bar = Foo;

这会产生以以下开头的错误:

c:\Program Files\Microsoft Visual Studio 9.0\VC\include\xxcallfun(7) : error C2562: 'std::tr1::_Callable_fun<_Ty>::_ApplyX' : 'void' function returning a value

这是 VS2008 TR1 实现的失败吗?这在VS2010中有效吗? TR1 是否解决了此功能? C++0x 怎么样?

【问题讨论】:

  • void g() { return f(); } 允许支持模板代码,其中函数的返回类型可能事先不知道......如果@987654328 实际返回值,f() 仍然是错误的@ 才不是。鉴于此,我不会惊讶地发现标准委员会选择在这方面与 Boost 的实现有所不同,因为它提供了更直观的行为。但由于 gcc 确实 允许这种行为,我并不肯定。

标签: c++ c++11 tr1 boost-function


【解决方案1】:

我相信 tr1 解决了这个问题。 N1836(最新的 tr1 草案)说:

F 类型的函数对象 f 是 可调用参数类型 T1、T2、 ...,TN 和返回类型 R,如果,给定 左值 t1, t2, ..., tNoftypesT1, T2, ..., TN, 分别, INVOKE(f, t1, t2, ..., tN) 是良构的 ([3.3]) 并且,如果 R 不为 void,可转换为 R。

在您的示例中,R 是无效的,因此Callable(可转换为 R)的最后一部分要求被忽略。

但是看起来 C++0x (C++11) 改变了规则。在 C++11 中,Callable 定义为 INVOKE(f, t1, t2, ..., tN, R),在 [func.require] 中定义为要求 INVOKE(f, t1, t2, ..., tN) 隐式转换为 R,当 R 为 void 时也不例外。所以在 C++11 中,你的例子应该会失败。

【讨论】:

  • 你知道这种变化/回归是否有理由吗?如果没有,这听起来像是一个缺陷。
  • 这听起来确实很奇怪。没有表达式可以隐式转换为void。甚至没有 void 类型的表达式(根据第 4 条第 3 款)。需要一个明确的转换来将事物转换为void。我想意图是只有当结果类型与R不同时,表达式才会隐式转换为R。那么当Rvoid 时,结果仍可能具有void 类型。不过,这些段落很容易被欺骗,IMO :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多