【问题标题】:Convert constexpr struct to a runtime one将 constexpr 结构转换为运行时结构
【发布时间】:2017-09-27 13:19:49
【问题描述】:

我正在尝试使用模板类(此处为 Foo),其基本类型如下:

  • hana::tuple<hana::pair<hana::type<int>, Runtime>>Runtime 显然不能是 constepxr 的类。

但类型可以通过多种方式构造,这就是我使用的原因:

  • hana::tuple<hana::pair<hana::type<int>, hana::type<Runtime>>> 在编译时完成工作。

所以问题基本上是如何从第一个元组类型转换为第二个元组类型。我想知道hana 中是否有什么可以帮助我。甚至更好的是,关于这种“转换”的一些技巧。

namespace hana = boost::hana;
using namespace hana::literals;

struct Runtime { std::vector<int> data; };

template < typename T >
struct Foo {
  T data;
};

constexpr decltype(auto)  convertMap(auto storageMap) {

return hana::make_type(hana::transform(
    storageMap,
    [] (auto pair) {
      return hana::make_pair(
        hana::first(pair),
        typename decltype(hana::typeid_(hana::second(pair)))::type {});
    }));
}

int main() {

  constexpr auto map = hana::make_tuple(
      hana::make_pair(hana::type_c<int>, hana::type_c<Runtime>)
      );

  constexpr auto result = convertMap(map);
  static_assert(result ==
     hana::type_c<hana::tuple<hana::pair<hana::type<int>, Runtime>>>);

  Foo<typename decltype(result)::type> test;
}

如你所见,我尝试了一些 c++1z convertMaphana::transformlambdas,但第二个元组不能是 constexpr,所以我不能将它传递给 hana::make_type 希望获取hana::type_c

test.cpp: In function ‘int main()’:
test.cpp:70:41: error: ‘constexpr decltype(auto) convertMap(auto:27) [with auto:27 = boost::hana::tuple<boost::hana::pair<boost::hana::type_impl<int>::_, boost::hana::type_impl<Runtime>::_> >]’ called in a constant expression
   constexpr auto result = convertMap(map);
                                         ^
test.cpp:53:27: note: ‘constexpr decltype(auto) convertMap(auto:27) [with auto:27 = boost::hana::tuple<boost::hana::pair<boost::hana::type_impl<int>::_, boost::hana::type_impl<Runtime>::_> >]’ is not usable as a constexpr function because:
 constexpr decltype(auto)  convertMap(auto storageMap) {
                           ^~~~~~~~~~
test.cpp:53:27: error: temporary of non-literal type ‘boost::hana::tuple<boost::hana::pair<boost::hana::type_impl<int>::_, Runtime> >’ in a constant expression
In file included from /usr/include/boost/hana/detail/struct_macros.hpp:29:0,
                 from /usr/include/boost/hana/adapt_adt.hpp:15,
                 from lib/hana/include/boost/hana.hpp:59,
                 from test.cpp:1:
/usr/include/boost/hana/tuple.hpp:68:12: note: ‘boost::hana::tuple<boost::hana::pair<boost::hana::type_impl<int>::_, Runtime> >’ is not literal because:
     struct tuple
            ^~~~~
/usr/include/boost/hana/tuple.hpp:68:12: note:   ‘boost::hana::tuple<boost::hana::pair<boost::hana::type_impl<int>::_, Runtime> >’ has a non-trivial destructor

【问题讨论】:

    标签: c++ metaprogramming constexpr c++17 boost-hana


    【解决方案1】:

    你只关心一个类型——因此你可以在非constexpr实现函数中隐藏类型的计算,然后用decltype(...){}调用它到“force constexpr” em>:

    template <typename T>
    decltype(auto) convertMapImpl(T storageMap)
    {
        return hana::make_type(hana::transform(storageMap, [](auto pair) {
            return hana::make_pair(hana::first(pair),
                typename decltype(hana::typeid_(hana::second(pair)))::type{});
        }));
    }
    
    template <typename T>
    constexpr decltype(auto) convertMap(T storageMap)
    {
        return decltype(convertMapImpl(storageMap)){};
    }
    

    live wandbox example


    另请注意,在函数签名中使用 auto 是 gcc 扩展 - 您应该使用 模板参数 来代替标准兼容。

    【讨论】:

    • 我想要一些提示,你给了我一个非常感谢 :) 关于汽车的抱歉,我又忘记了。
    猜你喜欢
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2017-02-09
    • 2015-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多