阅读了很多关于模板、模板特化和部分特化的文章后,我仍然无法理解以下模板巫术的工作原理和原因。
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<Ret (Arg)>
? void (int x)
如何/为什么匹配专业class Signal<Ret (Arg)>
?为什么是template <class Arg, class Ret>
甚至有必要?为什么不直接使用 <>
与“正常”专业一样? class Arg
的顺序和 class Ret
似乎并不重要,为什么?
如果这些问题没有任何意义,我很抱歉。如果他们不这样做,请不要费心直接回答他们。我只想了解上述代码的工作原理和原因。谢谢。
最佳答案
问题在于 void(int x)
是单一类型,即采用 int
并返回 void
的函数类型(参数名称 x
在这里被忽略)并且此类型绑定(bind)到 Signal
中的 T
。但是这种情况有一个专门化,所以它被选中并且 Ret
绑定(bind)到 void
和 Arg
绑定(bind)到 int
。 在模板参数列表中的顺序无关紧要,但是在专用参数中使用它们的位置却很重要,因为传递的参数将以这种方式绑定(bind)到不同的东西。
同样的事情也适用于数组类型:
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;
}
关于c++ - 这些具有函数签名(如参数)的模板特化如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21339051/