9

boost::function FAQ item 3专门解决了我感兴趣的场景:

为什么有无效退货的解决方法?C++ 允许它们!C++ 标准允许无效返回,如以下代码片段所示:

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

这是 boost::function 的有效用法,因为不使用 void 返回。使用 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 怎么样?

4

1 回答 1

8

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

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

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

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

于 2011-07-08T19:09:45.570 回答