【问题标题】:How does these template specializations with function signature like arguments work?这些具有函数签名(如参数)的模板特化如何工作?
【发布时间】:2014-01-24 17:45:06
【问题描述】:

阅读了很多关于模板、模板特化和部分特化的文章,我仍然无法理解以下模板巫术的工作原理和原因。

template <class T> class Signal;
template <class Arg, class Ret>
class Signal<Ret (Arg)> {
  typedef std::function<Ret (Arg)> Callback;
};

int main() {
  Signal<void (int x)> signal;
}

我对代码的作用以及如何使用它有相当好的了解,但我只是不明白为什么以及如何使用它。编译器如何解释包含空格和括号的特化参数,例如class Signal&lt;Ret (Arg)&gt;void (int x) 如何/为什么与专业化 class Signal&lt;Ret (Arg)&gt; 匹配?为什么template &lt;class Arg, class Ret&gt; 甚至是必要的?为什么不像在“普通”专业中那样使用&lt;&gt;class Argclass Ret 的顺序似乎无关紧要,为什么?

如果这些问题没有任何意义,我很抱歉。如果他们不这样做,请不要费心直接回答他们。我只想了解上述代码的工作原理和原因。谢谢。

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    问题是void(int x)是单一类型,即取int并返回void的函数的类型(这里忽略了参数名称x)并且这个类型绑定到TSignal。但是这种情况有一个专门化,所以它被选中并且Ret 绑定到voidArgint模板参数列表中的顺序无关紧要,但在专用参数中使用它们的位置却很重要,因为传递的参数将以这种方式绑定到不同的东西。

    同样的事情也适用于数组类型:

    template <typename T>
    struct C;
    
    template <typename Element, std::size_t size>
    struct C<Еlement[size]> {};
    
    int main() {
        C<int[42]> c;
    }
    

    你所谓的“普通”特化实际上被命名为完全特化,因为它们不需要提供额外的参数来形成一个类型,因此是空的模板参数列表。您的示例和上面的示例称为部分特化,也可用于其他模板:

    template <typename T, int size>
    struct Array {};
    
    template <typename Element, std::size_t size>
    struct C<Array<Еlement, size>> {};
    
    int demo() {
        C<Array<int, 10>> a;
    }
    

    【讨论】:

      【解决方案2】:

      具有单个模板参数的模板定义:

      template <class T> class Signal;
      

      使用具有返回值(或 void)和参数的函数专门化模板:

      template <class R, class A>
      class Signal<R (A)> {
        typedef std::function<R (A)> Callback;
      };
      

      使用具有返回值(或 void)和两个参数的函数专门化模板:

      template <class R, class A0, class A1>
      class Signal<R (A0, A1)> {
        typedef std::function<R (A0, A1)> Callback;
      };
      

      等等……

      即使每个特化都是一个带有多个参数的模板,它指的是一个函数签名的单一模式。 “正常”的特化不能描述一组函数签名,而是一个单独的:

      template <>
      class Signal<void (int)> {
        typedef std::function<void (int)> Callback;
      };
      

      注意:只有特化中模板参数的顺序(例如:Signal)是相关的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-06
        • 1970-01-01
        • 1970-01-01
        • 2018-06-25
        相关资源
        最近更新 更多