Dmi*_*ich 15 c++ lambda future variant c++17
我正在玩,std::variant, lambdas
并且std::future
当我试图将它们组合在一起时得到超级奇怪的结果.以下是示例:
using variant_t = std::variant<
std::function<std::future<void>(int)>,
std::function<void(int)>
>;
auto f1 = [](int) { return std::async([] { return 1; }); };
auto f2 = [](int) { return std::async([] { }); };
variant_t v1(std::move(f1)); // !!! why DOES this one compile when it SHOULDN'T?
auto idx1 = v1.index(); //equals 1. WHY?
variant_t v2(std::move(f2)); // !!! why DOESN'T this one compile when it SHOULD?
Run Code Online (Sandbox Code Playgroud)
这是编译错误:
错误C2665'std :: variant <std :: function <std :: future <void>(int)>,std :: function <void(int)>> :: variant':2个重载中没有一个可以转换所有的参数类型
OK,让改变variant
从返回的项目签字void
到int
:
using variant_t = std::variant<
std::function<std::future<int>(int)>,
std::function<int(int)>
>;
variant_t v1(std::move(f1)); // COMPILES (like it should)
auto idx1 = v1.index(); // equals 0
variant_t v2(std::move(f2)); // DOESN'T compile (like it should)
Run Code Online (Sandbox Code Playgroud)
这到底是怎么回事?为什么std::future<void>
这么特别?
Col*_*mbo 16
variant
转换构造函数模板采用重载决策来确定构造对象应该具有哪种类型.特别是,这意味着如果对这些类型的转换同样好,则构造函数不起作用; 在你的情况下,如果其中一个特化std::function
是可以从你的参数构造的,那么它是有效的.
那么什么时候可以function<...>
从给定的参数构造?从C++ 14开始,如果参数可以使用参数类型调用,并生成一个可转换为返回类型的类型.请注意,根据此规范,如果返回类型是void
,则任何内容都会发生(因为任何表达式都可以转换为void
withstatic_cast
).如果你有一个function
返回void
,你传入的仿函数可以返回任何东西 - 这是一个功能,而不是一个错误!这也是function<void(int)>
适用的原因f1
.另一方面, future<int>
不转换为future<void>
; 因此只有function<void(int)>
可行,变量的索引是1.
但是,在第二种情况下,lambda返回future<void>
,可以转换为future<void>
和void
.如上所述,这导致两种特化都是function
可行的,这就是为什么variant
不能决定构建哪一种.
最后,如果您将返回类型调整为int
,void
则避免了整个转换问题,因此一切都按预期工作.
归档时间: |
|
查看次数: |
542 次 |
最近记录: |