你可以找到另一种方式来显式实例化template
,你可以对它进行元编程。
然后,不要每行都做一个实例化,请将它们全部做成一个包。对它们运行一个n^2算法(在编译时)以消除重复(或者,老实说,你可能会跳过:取决于你如何实例化模板,它可能不在意)。
事情是这样的,假设Instantiate< Template, types< blah, foo, bar > >
实际实例传递作为第一个参数中的模板列表:
#include <utility>
#include <type_traits>
template<typename T>
struct Test {};
template<typename... Ts>
struct types {};
template<template<typename>class Template, typename Types>
struct Instantiate {};
template<template<typename>class Template, typename T0, typename... Ts>
struct Instantiate<Template, types<T0, Ts...>>:
Instantiate<Template, types<Ts...>>
{
Template<T0>& unused();
};
template<typename U, typename Types>
struct prepend;
template<typename U, template<typename...>class pack, typename... Ts>
struct prepend< U, pack<Ts...> > {
typedef pack<U, Ts...> types;
};
template<typename U, typename Types>
using Prepend = typename prepend<U, Types>::types;
template<typename U, typename Types, typename=void>
struct remove_type_from_types;
template<typename U, template<typename...>class pack>
struct remove_type_from_types<U, pack<>, void>
{
typedef pack<> types;
};
template<typename U, template<typename...>class pack, typename T0, typename... Ts>
struct remove_type_from_types< U, pack<T0, Ts...>,
typename std::enable_if< std::is_same<U, T0>::value >::type
>: remove_type_from_types< U, pack<Ts...> >
{};
template<typename U, template<typename...>class pack, typename T0, typename... Ts>
struct remove_type_from_types< U, pack<T0, Ts...>,
typename std::enable_if< !std::is_same<U, T0>::value >::type
>
{
typedef Prepend< T0, typename remove_type_from_types< U, pack<Ts...> >::types > types;
};
template<typename Types>
struct remove_duplicates {
typedef Types types;
};
template<template<typename...>class pack, typename T0, typename... Ts>
struct remove_duplicates<pack<T0, Ts...>> {
private:
typedef typename remove_type_from_types< T0, pack<Ts...> >::types filtered_tail;
typedef typename remove_duplicates<filtered_tail>::types unique_tail;
public:
typedef Prepend< T0, unique_tail > types;
};
template<typename Types>
using RemoveDuplicates = typename remove_duplicates<Types>::types;
static Instantiate<Test, RemoveDuplicates<types<int, double>> > unused;
int main() {
}
如前所述,你也许可以与整个消除,重复位做掉,因为如何我正在实例化使用template
。我也不确定每个template
的上述用法是否足以实例化它(即,它不会被优化掉,并且符号将被导出)。我怀疑Fancier独特类型的去除是很困难的,这对于任何合理数量的类型来说都足够浅和足够快,我们认为,类型数量递归深度为n
,并且总共完成的工作量为n^2
。 ,由于缺乏裸体类型的弱排序......)
我个人在头文件中保存模板代码,并让编译器根据需要自动实例化它。我想在某些情况下,尽管会扩大编译时间。 – Dave