【问题标题】:hana::tuple to auto && ... argshana::tuple to auto && ... args
【发布时间】:2017-09-19 13:24:16
【问题描述】:

有没有办法使用类似的东西:

constexpr auto foo = hana::make_tuple(hana::type_c<Foo1>,hana::type_c<Foo2>);

类似:

template < typename ... Ts >
struct Final {

  constexpr Final(Ts && ... args) {}
};

hana::unpack(foo, [] (auto && ... args) { return Final(args...); });

因为使用该代码,unpack 无法推断出 lambda/函数类型。 基本上我想创建一个接受参数列表的类型,但我有一个包含参数的元组。

【问题讨论】:

  • 该代码不是有效的 C++14 或 C++17。您在使用概念画板吗?
  • @KerrekSB 我这里不需要概念,你能告诉我为什么它是无效的吗?
  • auto 不是 C++ 中的有效函数参数类型。它只允许在 lambda 表达式中使用。
  • auto 是一个函数参数类型,属于概念 TS (-fconcepts)。
  • @serup 实际上,如果您的编译器开始实现 Concepts TS,则 auto 将起作用。您不需要使用 gcc 指定任何标准,甚至不需要 -fconcept。

标签: c++ c++14 metaprogramming boost-hana


【解决方案1】:

问题出在你的 lambda 中:

[](auto && ... args){ return Final(args...); }
//                          ~~~~~~~

Final 不是类型,它是类模板。因此,您需要显式提供类型。比如:

[](auto&&... args){ return Final<decltype(args)...>(
    std::forward<decltype(args)>(args)...); }

在 C++17 中,使用类模板参数的模板推导,Ts&amp;&amp; 不能用作转发引用(请参阅related answer),因此隐式推导指南无论如何都不会与您的用法相匹配,因为您只是提供左值和指南需要重估。但这会起作用:

[](auto... args){ return Final(std::move(args)...); }

【讨论】:

  • 如果构造函数按值获取 Ts 并在那里而不是在 lambda 中执行 std::move 可能会更好。
  • 我认为在第二个代码 sn-p 中应该是Final&lt;decltype(args)&amp;&amp; ...&gt; 以便完美转发(--注意&amp;&amp;)。
  • @davidhigh 他们的意思是一样的——decltype(args) 在这里始终是一个参考。
  • “这里”的意思是在 OP 的上下文中,我猜,局部变量 foounpack'ed。但这通常不成立,如果我理解正确的话,因为args 可能是一个右值引用,但decltype(args) 被推断为左值引用。
  • @davidhigh 这里的意思是你建议改变的地方。
【解决方案2】:

如果我正确理解您的问题,那么您真正要寻找的是

template <typename ...Ts>
struct Final { ... };

constexpr auto foo = hana::make_tuple(hana::type_c<Foo1>,hana::type_c<Foo2>);
auto final_type = hana::unpack(foo, [](auto ...args) {
  return Final<typename decltype(args)::type...>;
});
// now, final_type is a hana::type<Final<Foo1, Foo2>>

你也可以使用hana::template_实现同样的目的:

constexpr auto foo = hana::make_tuple(hana::type_c<Foo1>,hana::type_c<Foo2>);
auto final_type = hana::unpack(foo, hana::template_<Final>);

我从 Barry 的回答中看到的问题是,您最终会创建一个 Final&lt;decltype(hana::type_c&lt;Foo1&gt;), decltype(hana::type_c&lt;Foo2&gt;)&gt;,这可能不是您想要的。

【讨论】:

  • 我认为你受到了我之前的问题的影响,因为我的目标不是用类型的元组创建最终类型。如果您想要更多上下文,我在这里使用 Jason Rice 解决方案:stackoverflow.com/questions/43089587/…,我想加入几个 multi_map。或者我只是误解了你的回答对不起^^"
  • 不用担心。我要说的是,使用 Barry 的解决方案,如果你这样做 unpack(foo, the-lambda-he-provided),你最终会得到 Foo&lt;type&lt;Foo1&gt;, type&lt;Foo2&gt;&gt;,这似乎有点奇怪。无论如何,我很高兴 Barry 的解决方案解决了您的问题。
  • 啊,没错。 Barry 的回答没有解决 OP foohana::type 的元组这一事实。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-26
  • 1970-01-01
  • 1970-01-01
  • 2014-07-31
  • 2020-12-28
相关资源
最近更新 更多