我可以使用元编程将类型列表转换为对列表中的每个类型具有特定隐式转换行为的新类型吗?

时间:2017-11-10 03:55:47

标签: c++ metaprogramming boost-mpl

我有一个包含多种类型的import React, { Component } from 'react' import { Text, View, FlatList, StyleSheet } from 'react-native' import SearchCard from './SearchCard' export default class SearchList extends Component { wrapperStyle (index) { return index > 0 ? styles.listItemWrapper : [styles.listItemWrapper, styles.wrapperFirst] } _renderItem = ({item, index}) => ( <View style={this.wrapperStyle(index)}> <SearchCard search={item} id={item.id} filterAttributes={this.props.filterAttributes} onSearch={this.props.onSearch} onFavorite={this.props.onFavorite} favorites={this.props.favorites} /> </View> ) render () { const { searches, filterAttributes, onSearch, onFavorite, favorites } = this.props return ( <FlatList data={searches} extraData={{ filterAttributes: filterAttributes, onSearch: onSearch, onFavorite: onFavorite, favorites: favorites, searches: searches }} keyExtractor={item => item.id} renderItem={this._renderItem} enableEmptySections style={{backgroundColor: 'red'}} /> ) } } const styles = StyleSheet.create({ wrapperFirst: { marginTop: 20 }, listItemWrapper: { marginLeft: 20, marginRight: 20, marginBottom: 20 } }) ,例如

boost::mpl::vector

对于某些已知类型typedef boost::mpl::vector<T1, T2, T3, T4> list_type; 。是否有任何方法可以使用元编程将此列表转换为表示直接线性继承的类型,按照向量中的类型顺序?我想合成一种具有与此一致的行为的类型:

T1, T2, T3, T4

enter image description here给了我类似的行为,但不完全是我想要的。使用时产生的类型更像:

struct T1 { };
struct T2 : T1 { };
struct T3 : T2 { };
struct T4 : T3 { };
struct synthesized_type : T4 { };

在某些情况下表现不同。例如,假设您有一个在struct synthesized_type : T1, T2, T3, T4 { }; 类型的某个子集上重载的函数:

T1, T2, T3, T4

使用上面给出的第一个(所需)层次结构,重载决策没有歧义;我可以将void foo(T1) { } void foo(T3) { } foo(synthesized_type()); // I would like to be able to do this 传递给synthesized_type,它会调用foo(),因为foo(T3)T3祖先中派生程度最高的类型。

但是,在我使用synthesized_type的情况下,由于重载决策的模糊性,这会导致编译器错误,因为父类型之间没有指定优先级;编译器无法在boost::mpl::inherit_linearlyfoo(T1)之间进行选择。

有没有办法得到我想要的效果?更正式地说:

  

给定一个类型列表,我想使用元编程来合成一些具有上述第一层次结构属性的类型(即,合成类型可以隐式转换为每种类型foo(T3),按此顺序排列优先级,因此T1, T2, T3, T4优先于T4,优先于T3,依此类推。这可能吗?

1 个答案:

答案 0 :(得分:2)

如果你的类型都是CRTP类型,你可以做这个巫术:

#include <iostream>

template< template<class> class... Ts >
struct TVec { };

struct EmptyClass { };

template< class T >
struct Inheritor;

template< template<template<class> class> class U, template<class> class T>
struct Inheritor< U<T> >
  : public T<EmptyClass> { };

template< template<template<class> class...> class U, template<class> class T, template<class> class... Ts>
struct Inheritor< U<T, Ts... > >
  : public T<Inheritor< U<Ts...> > > { } ;

template< typename Base >
struct T1
  : public Base { };

template< typename Base >
struct T2
  : public Base { };

template< typename Base >
struct T3 
  : public Base { };

template<typename X>
void foo(T1<X> t) {
  std::cout << "T1" << std::endl;
}

template<typename X>
void foo(T2<X> t) {
  std::cout << "T2" << std::endl;
}

template<typename X>
void foo(T3<X> t) {
  std::cout << "T3" << std::endl;
}

int main() {
  using Types = TVec< T1, T2, T3 >;
  using Types2 = TVec< T3, T2, T1 >;

  using Derived = Inheritor<Types>;
  using Derived2 = Inheritor<Types2>;

  //Inheritor<TVec< T1, T2, T3>> x;
  Derived x;
  Derived2 x2;

  foo(x); // T1 overload
  foo(x2); // T3 overload
}

你不能得到那种确切的行为,因为它涉及重新定义T1,T2 ......这是否足够接近?

template< class T >
struct Inheritor { };

template< class T, template<class> class U >
struct Inheritor< U<T> >
  : public T { };

template< template<class...> class U, class T, class... Ts >
struct Inheritor< U<T, Ts...> >
  : public T
  , public Inheritor< U< Ts... > > { };