来自boost::async()的boost::future<>类型

4

我在使用 boost::async() (Boost 1.56, Windows: VS2010 和 VS2012) 时得到了意外的结果。

#include <boost/thread/future.hpp>
...
auto func = [](){ return 123; };
auto boostFut = boost::async(func);
// boostFut = 42; // intentional error to reveal deduced type in compilation error

由于某种原因,boostFut 被推断为 boost::unique_future<void> 而不是 boost::unique_future<int>

我做错了什么?

注意:在 VS2012 上,如果我使用 std::async(func) 而不是 boost::async(func),那么它会按预期工作,并且 future 的类型被推断为 int


boost 的版本是有用的。另外,有时候 boost 函数需要在传入的函数对象中使用 result_type 类型定义。 - Yakk - Adam Nevraumont
如上所述:Boost 1.56。您能详细说明一下result_type建议吗?即使我明确定义了boost::unique_future<int> boostFut = ...,问题仍然存在,此时asyn()分配无法编译。 - Adi Shavit
抱歉,我错过了那个。我知道一些boost函数适配器要求传入对象中的结果类型必须是明确的,或者至少会在无法解决问题时退而求其次。您的问题是否可以通过函数指针解决?例如 struct foo { typedef int result_type; int operator()() const { return 42; };? 或者没有 result_typefoo - Yakk - Adam Nevraumont
2
@AdiShavit 请尝试在包含boost库之前添加#define BOOST_RESULT_OF_USE_DECLTYPE - Piotr Skotnicki
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Adi Shavit
1个回答

4

boost::async 需要确定参数函数对象调用的结果类型。为了做到这一点,Boost 使用它自己的 boost::result_of<T> 类模板实现。也就是说,async 的声明如下:

template <class F>
boost::future<typename boost::result_of<typename boost::decay<F>::type()>::type>
async(F f);

根据编译器的能力/boost的配置,boost::result_of<T>特性可以通过以下两种方式之一工作:

  1. 使用调用表达式中的decltype()
  2. 查找F内部的嵌套result_type typedef或查找F内部的嵌套result<T>类模板(如果函数对象的参数数量大于零,可能存在重载)。

如果使用后一种方法(2),则以上两种替代方案都无法适用于lambda类型,因此Boost最终默认推断出将void作为返回类型来使用。

为了确保您的Boost实现将使用可正常工作的lambda调用表达式的decltype()运算符,您需要在引入Boost头文件之前添加一个定义:

#define BOOST_RESULT_OF_USE_DECLTYPE

或者将此定义添加到boost/config/user.hpp文件中。

非常好的回答。谢谢! - Adi Shavit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接