2017-06-19 93 views
1

我搜索了很多,可以找到许多类似的问题,但他们都没有解决这个特定的问题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...>; 

};

这不会工作,但我不明白为什么它不应该。它说,参数不抵扣的参数数量...和... Args2但对我来说应该是自然的,从调用现场猜:

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

从那里INT应该Args1 ......在模板专业化和字符Args2 ...

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

回答

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; 
}; 

现在,一旦你已经得到了这一点的办法,用专业化解包的元组类型,然后每次洗涤后重新包装它们一个使用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; 
+0

现在尝试。为什么不能直接使用我所尝试的?如果可能的话,我也想深入了解一下。无论如何,尝试后,我很高兴接受答复,因为它的工作原理。 –

+3

因为参数包[无法推导,除非包是最后一个模板参数](https://stackoverflow.com/questions/14768951/variadic-function-template-with-pack-expansion-not-in-last-parameter ),所以你的'std :: tuple '在燃烧的残骸中坠落,因为它试图推导出一个不是最后一个模板参数的参数包。 –

+1

Upvoting为完成良好的工作实现和*在燃烧的残骸*下降。不过,主要是因为*燃烧的残骸。 –

相关问题