c++ - 这些具有函数签名(如参数)的模板特化如何工作?

标签 c++ templates

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

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)到 voidArg 绑定(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/

相关文章:

c++ - 在类外设置 const int 成员变量 (C++)

c++ - 从具有自定义类型的 C++ 中的 std::map 获取值

c++ - QTextEdit 中的不可见文本

c++ - 如何改善我的文件写入方法以减小Wavefront Object文件的大小?

c++ - 尝试将观察者注册到模板主题类时出现编译错误

c++ - 模板对象数组

c++ - 指向成员变量和模板

c# - 如何在 C# 中将 System.IO.BinaryWriter 与模板/泛型类型的数组一起使用?

php - 如何在模块中使用 ExpressionEngine 表单验证类来重新填充模板中的表单?

c++ - 在任意加长的集合中查找最大数量是行不通的