实例化和未实例化模板的部分模板特化
Partial template specialization over instantiated and uninstantiated template
我有以下两个结构:
template<typename T>
struct one { /* ... */ };
template<template<typename...> typename T>
struct two { /* ... */ };
当我有这样的示例 instantiated/uninstantiated 模板时:
template<typename T>
struct sample_templated { /* ... */ };
using instantiated = sample_templated<double>;
那我可以
one<instantiated>{};
two<sample_templated>{};
就好了。我想合并 one
和 two
的定义,使它们具有相同的名称,因为这将允许递归。
我试过像
这样的默认定义
template<typename...>
struct types_match_impl;
并使两个原始结构成为其部分特化,但这与 two
.
不兼容
这里的解决方案是什么?
你希望的方式是不可能的。原因如下:
one<instantiated>{};
two<sample_templated>{};
one
"uses"多于two
:指的是instantiated
是sample_templated
实例化为 double
。另一方面,two
只是 "using" sample_templated
。
当您将模板视为类型上的函数时,这会变得更加清晰:two
是一个接受(类型级)函数来创建某种类型的函数。 one
是一个接受类型以创建某种类型的函数:
one :: T -> one<T>
two :: (T -> U) -> two<(T -> U)>
换句话说,one
的参数与 two
.
的参数不同 "kind" ("type of type")
你能做什么:
您可以提供 one
的特化,它接受模板模板参数 ("type level function") 和 模板参数:
template<template<typename...> typename TT, typename T>
struct one<TT<T>> { /* ... */ }; // this basically "calls" TT
您可以将 two
变成可以接受两者的东西,尽管使用 "dummy" 模板模板参数:
template<template<typename...> typename TT, typename... Ts>
struct two { /* */ };
template<typename...>
struct Void;
template<typename T>
struct two<Void<>, T> { /* Use T like in one */ };
// or derive from one<T>
可能还有更多方法,但这取决于您的具体用例。
我有以下两个结构:
template<typename T>
struct one { /* ... */ };
template<template<typename...> typename T>
struct two { /* ... */ };
当我有这样的示例 instantiated/uninstantiated 模板时:
template<typename T>
struct sample_templated { /* ... */ };
using instantiated = sample_templated<double>;
那我可以
one<instantiated>{};
two<sample_templated>{};
就好了。我想合并 one
和 two
的定义,使它们具有相同的名称,因为这将允许递归。
我试过像
这样的默认定义template<typename...>
struct types_match_impl;
并使两个原始结构成为其部分特化,但这与 two
.
这里的解决方案是什么?
你希望的方式是不可能的。原因如下:
one<instantiated>{};
two<sample_templated>{};
one
"uses"多于two
:指的是instantiated
是sample_templated
实例化为 double
。另一方面,two
只是 "using" sample_templated
。
当您将模板视为类型上的函数时,这会变得更加清晰:two
是一个接受(类型级)函数来创建某种类型的函数。 one
是一个接受类型以创建某种类型的函数:
one :: T -> one<T>
two :: (T -> U) -> two<(T -> U)>
换句话说,one
的参数与 two
.
你能做什么:
您可以提供
one
的特化,它接受模板模板参数 ("type level function") 和 模板参数:template<template<typename...> typename TT, typename T> struct one<TT<T>> { /* ... */ }; // this basically "calls" TT
您可以将
two
变成可以接受两者的东西,尽管使用 "dummy" 模板模板参数:template<template<typename...> typename TT, typename... Ts> struct two { /* */ }; template<typename...> struct Void; template<typename T> struct two<Void<>, T> { /* Use T like in one */ }; // or derive from one<T>
可能还有更多方法,但这取决于您的具体用例。