2011-07-08 88 views
9

升压::功能FAQ item 3专门针对我感兴趣的场景:可以tr1 ::函数swallow返回值吗?

为什么有解决方法的空白 回报? C++允许他们!空返回 由C++标准允许的,如在 此代码段:

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

这是 升压::函数的一个有效的使用,因为空返回 不被使用。随着空返回,我们 会试图编译形成不良的类似 代码:

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

在本质上,没有使用的空返回 允许的boost ::功能吞下 返回值。这与 一致,允许用户分配和调用 功能和功能对象与 参数不完全匹配。

不幸的是,这并不在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?

+0

VS2010给出了同样的错误。 – Xeo

+2

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

回答

8

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

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

在您的例子R是无效的,所以要求用于Callable(转化为R)的最后部分是忽略d。

但它看起来像C++ 0x(C++ 11)更改规则。在C++ 11中,Callable被定义为INVOKE(f, t1, t2, ..., tN, R),它在[func.require]中定义为要求INVOKE(f, t1, t2, ..., tN)可隐式转换为R,R无效时无一例外。所以在C++ 11中,你的例子应该会失败。

+2

你知道这个改变/回归是否有理由吗?如果没有,这听起来像是一个缺陷。 –

+0

这听起来很奇怪。没有表达式可以隐式转换为'void'。甚至没有“空白”类型的表达(根据第4条第3款)。一个需要明确的演员将事物转换为“空白”。我想这意味着只有当结果类型与“R”不同时,表达式才会隐式转换为“R”。那么当'R'为'void'时,结果仍然可以有'void'类型。被这些段落欺骗很容易,IMO :) –

相关问题