匹配部分特化以按类型替换元组元素

时间:2017-06-19 03:38:43

标签: c++ c++14 variadic-templates template-meta-programming

我搜索了很多,可以找到许多类似的问题,但没有一个能解决这个特殊问题AFAIK。

我想按类型(而不是索引)替换元组中的类型。我试过这样的事情:

template <class Tuple, class ToRemove, class ToReplace>
struct ReplaceType {
     using type = Tuple;
};

template <class ToRemove, class ToReplace, class...Args, class...Args2>
struct ReplaceType<std::tuple<Args..., ToRemove, Args2...>, ToRemove, ToReplace> {
    using type = std::tuple<Args..., ToReplace, Args2...>;

};

这不会奏效,但我不明白为什么不应该这样做。它说参数不能用于Args ...和Args2 ...但对我来说,从呼叫站点猜测它应该是很自然的:

typename ReplaceType<std::tuple<int, float, char>, float, double>>::type;

从那里int应该是模板特化中的Args1 ...和char Args2 ...

  1. 为什么这不起作用?
  2. 有解决方法吗?

1 个答案:

答案 0 :(得分:2)

一次一步。

首先,使用专门化将一种类型映射到另一种类型,保持所有其他类型不变。如果TToRemove,请将其替换为“ToReplace”,否则请将其单独使用:

template<typename T, typename ToRemove, typename ToReplace>
struct replace_type {

    using type=T;
};

template<typename ToRemove, typename ToReplace>
struct replace_type<ToRemove, ToRemove, ToReplace> {

    using type=ToReplace;
};

现在,一旦你已经解决了这个问题,请使用specialized来解包元组类型,然后在使用replace_type清洗每个类型之后重新打包它们:

template<class Tuple, typename ToRemove, typename ToReplace>
struct replace_tuple;

template<typename ...Args, typename ToRemove, typename ToReplace>
struct replace_tuple<std::tuple<Args...>, ToRemove, ToReplace> {

    using type=std::tuple<typename
                  replace_type<Args, ToRemove, ToReplace>::type
                  ...>;
};

使用gcc 6.3.1进行测试:

replace_tuple<std::tuple<int, char, int>, char, unsigned>::type foo;

std::tuple<int, unsigned, int> *bar=&foo;