以下代码来自an answer to another question,它有效。我用最新版本的GCC,Clang,ICC和MSVC测试了它。但我不明白标准的哪一部分允许这种结构,请你帮忙吗?
template<class F, class Alloc> class C; //undefined
template<class T, class... Args, class Alloc>
class C<T(Args...), Alloc> {
// implementation
};
C ++标准提供了如何在主类模板中使用参数包的约束,但我无法弄清楚它们如何应用于部分特化。
所以我的问题是:在C ++标准中定义的部分模板特化的上下文中,参数包的放置规则在哪里?
答案 0 :(得分:1)
虽然不是正式和技术上正确的方式来理解部分专业化如何工作(请查看the cppreference page以获得更多技术说明),但您可以考虑使用术语发布的代码段“模式匹配”(仅作为直觉):
// `C` is a template class that takes two types as template parameters.
template<class F, class Alloc> class C;
// I'm going to specialize `C` so that:
// * The first type will be a function signature type, where the return
// type is going to be matched by `T` and the argument types will be
// matched by `Args...`.
// * The second type will be an user-provided `Alloc` typename.
template<class T, class... Args, class Alloc>
class C<T(Args...), Alloc> { /* ... */ };
假设我像这样实例化C
:
using My_C = C<int(float, char), std::allocator<int>>;
My_C c;
非常粗略地说,My_C
将“匹配” C<T(Args...), Alloc>
部分模板专精化,如下所示:
int ( float, char ) std::allocator<int>
^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
T ( Args... ) Alloc
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
F Alloc
{p> int
“匹配” T
,float, char
“匹配” Args...
。我们没有理由将Args...
限制为C
的最后一个模板参数。
正如您所看到的,Args...
参数包不是最后一个模板参数,因为我们只是使用它为传递函数中的参数类型列表“提供名称”签名。