tr1::function 可以吞掉返回值吗?
boost::function 常见问题解答第 3 项 具体解决我感兴趣的场景:
为什么有 void 的解决方法 回报? C++ 允许它们!无效退货 C++ 标准允许,如 在此代码片段中:
void f(); 无效 g() { 返回 f(); }
这是一个有效的用法 boost::function 因为 void 返回 没有被使用。对于无效退货,我们 会尝试编译格式错误的 代码类似于:
int f(); 无效 g() { 返回 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 怎么样?
The boost::function FAQ item 3 specifically addresses the scenario I am interested in:
Why are there workarounds for void
returns? C++ allows them! Void returns
are permitted by the C++ standard, as
in this code snippet:void f(); void g() { return f(); }
This is a valid usage of
boost::function because void returns
are not used. With void returns, we
would attempting to compile ill-formed
code similar to:int f(); void g() { return f(); }
In essence, not using void returns
allows boost::function to swallow a
return value. This is consistent with
allowing the user to assign and invoke
functions and function objects with
parameters that don't exactly match.
Unfortunately, this doesn't work in VS2008:
int Foo();
std::tr1::function<void()> Bar = Foo;
This produces errors starting with:
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
Is this a failing of the VS2008 TR1 implementation? Does this work in VS2010? Does TR1 address this capability? How about C++0x?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我相信 tr1 解决了这个问题。 N1836(最新的 tr1 草案)说:
在您的示例中,R 为 void,因此忽略了 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 中,您的示例应该会失败。I believe tr1 addresses this issue. N1836 (the latest tr1 draft) says:
In your example R is void, and so the last part of the requirements for
Callable
(convertible to R) is ignored.However it looks like C++0x (C++11) changes the rules. In C++11
Callable
is defined asINVOKE(f, t1, t2, ..., tN, R)
which is defined in [func.require] as requiringINVOKE(f, t1, t2, ..., tN)
to be implicitly convertible to R, with no exception for when R is void. So in C++11, your example should fail.