重用可变参数类型

米海·加洛斯(Mihai Galos)

在以下C ++ 14代码中,我想使用可变参数模板创建一个可能类型的容器。接下来,我想用先前指定类型的成员元组创建另一个容器。

这样怎么办?我希望Foo包含<int,double>的元组,就像主题的模板化类型一样。

提前谢谢了。

#include <iostream>
#include <tuple>
#include <type_traits>

template <typename... T>
struct PossibleTypes {};

PossibleTypes<int,double> topics;

template <typename... T>
struct Foo{
    std::tuple<T...> member;
};

int main(){
    Foo<??(topics)??> x;
    return 0;
}
Yakk-亚当·内夫罗蒙特

有多种方法可以做到这一点。您不必全部了解它们,只需找到具有所需功能的组件即可。

这是三种非常不同的方法。

从实例转录到模板

template<class Src, template<class...>class Dest>
struct transcribe;
template<class Src, template<class...>class Dest>
using transcribe_t=typename transcribe<Src,Dest>::type;

template<template<class...>class Src, class...Ts, template<class...>class Dest>
struct transcribe<Src<Ts...>, Dest>{
  using type=Dest<Ts...>;
};

然后:

transcribe_t<decltype(topics), Foo> x;

通过修改Foo侵入

这也可以通过修改Foo为采用捆绑而不是打包的方式侵入性地完成

template <class Bundle>
struct Foo;

template <typename... T>
struct Foo<PossibleTypes<T...>>{
  std::tuple<T...> member;
};

要么

template <template<class...>class Z, typename... T>
struct Foo<Z<T...>>{
  std::tuple<T...> member;
};

然后:

Foo<decltype(topics)> x;

如果您不只是传入一组...参数,那将更加实用

基于价值的元编程

我们还可以使用基于值的元编程来解决此问题:

template<class T>
struct tag_t {constexpr tag_t(){} using type=T;};
template<class T>
constexpr tag_t<T> tag{};
template<template<class...>class Z>
struct ztemplate_t {
  constexpr ztemplate_t() {}
  template<class...Ts> using apply=Z<Ts...>;
  template<class...Ts>
  constexpr tag_t<Z<Ts...>> operator()(tag_t<Ts>...)const{ return {}; }
};
template<template<class...>class Z>
constexpr ztemplate_t<Z> ztemplate{};

template<class Tag>
using type=typename Tag::type;

template <class... T>
struct PossibleTypes {
  template<template<class...>class Z>
  constexpr auto operator()(ztemplate_t<Z> z) const {
    return z(tag<T>...);
  }
};

给我们:

int main(){
  type<decltype( topics(ztemplate<Foo>) ) > x;
  return 0;
}

这非常漂亮。现场例子

tag将类型提升为值。ztemplate将模板提升为一个值。

ztemplate<some_template>( tag<T0>, tag<T1> )返回一个tag应用的结果some_template,以T0, T1喜欢tag_t<some_template<T0, T1>>

要从标记移回类型,请执行type<decltype(some_tag_expression)>

我修改了您PossibleTypesoperator()(ztemplate),使它也将模板应用于存储在中的类型PossibleTypes

当您进行越来越多的基于类型的操作时,这种精神错乱会更好地发挥作用,因为C ++中基于值的编程比模板语法更具表现力且更易于使用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章