这里的目标是能够将参数包从模板实例复制到另一个模板。我没有将其限制为tuple
,因为...为什么将其限制为tuple
?
template<template<typename...>class Target, typename Src>
struct copy_pack_types;
template<template<typename...>class Target, template<typename...>class Src, typename... Ts>
struct copy_pack_types< Target, Src<Ts...> > {
typedef Target<Ts...> type;
};
template<template<typename... Ts>class Target, typename Src>
using CopyPackTypes = typename copy_pack_types<Target, Src>::type;
#include <string>
#include <tuple>
template<typename... Ts> struct vct;
template<typename... Ts> struct vct2;
using U = std::tuple<int,char,std::string>;
using X = vct<int,char,std::string>;
using Y = CopyPackTypes< vct, U >; // should be same as X
using Z = CopyPackTypes< vct2, U >; // should be different from X
#include <iostream>
#include <type_traits>
int main() {
std::cout << std::is_same< X, Y >::value << "\n";
std::cout << std::is_same< Z, Y >::value << "\n";
std::cout << std::is_same< Z, vct2<int,char,std::string> >::value << "\n";
}
正如预期的那样,输出是“1 0 1”。
CopyPackTypes
接受一个目标模板和一个从参数包构造的源类型作为它的唯一参数。然后它将参数包复制到目标模板。
一种标准技术是携带参数包是创建一个否则没有使用的类型,例如:
template<typename...>
struct types {};
它仅作为类型列表的占位符存在。然后,您可以将其中一些传递给另一个模板,并且每个包不会“踩”对方。当您需要将它应用到目标模板时,您可以使用类似上面的“ CopyPackTypes
”来应用它。
类似的技术用于索引包:
template<size_t...>
struct seq {};
否则无用的类型是“黑色石板”,用于携带大量参数。