已实例化和未实例化模板的部分模板特化

3

我有以下两个结构体:

template<typename T>
struct one { /* ... */ };

template<template<typename...> typename T>
struct two { /* ... */ };

当我有以下实例化/未实例化模板时:

template<typename T>
struct sample_templated { /* ... */ };

using instantiated = sample_templated<double>;

那么我可以做什么?

one<instantiated>{};
two<sample_templated>{};

没问题。我希望将onetwo的定义合并,这样它们就有了相同的名称,这将允许递归。

我尝试着使用默认的定义,例如:

template<typename...>
struct types_match_impl;

如何解决这个问题?

可以将两个原始结构体作为该结构体的部分特化,但这与“two”不兼容。


不太清楚您想要什么,但我猜您想将 types_match_impl 传递给它自己。您能展示一下您想编写的代码,并描述一下您认为它应该做什么吗? - jxh
1个回答

3
您希望的方式是不可行的。原因如下:
one<instantiated>{};
two<sample_templated>{};
< p >onetwo使用更多:它是指instantiated,它是用double实例化的sample_templated 实例化的。另一方面,two仅“使用”sample_templated

当您将模板视为类型的函数时,这变得更加清晰:two是一个函数,它接受(类型级)函数来创建某些类型。one是一个接受类型以创建某些类型的函数:

one :: T -> one<T>
two :: (T -> U) -> two<(T -> U)>

换句话说,one参数的“类型”(“类型的类型”)与two的不同。

您可以做什么:

  • You can provide a specialization of one which accepts a template template parameter ("type level function") and the template parameter for that:

    template<template<typename...> typename TT, typename T>
    struct one<TT<T>>  { /* ... */ }; // this basically "calls" TT
    
  • You can turn two into something which can accept both, albeit with a "dummy" template template parameter:

    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>
    

可能有更多的方法,但这些将取决于您具体的用例。


谢谢,我明白了。这个解决方案看起来很有希望,我会回来告诉你我的结果(顺便说一句:喜欢你加入了 Haskell :))。 - Post Self
很遗憾,在同一个可变参数包中不可能同时拥有两种“类型”,因此像我想象的那样进行递归是不可能的。 - Post Self
1
事实证明,对于我的设计,我甚至不需要未实例化的模板,但这些信息将对未来有所帮助。 - Post Self

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接