W.F*_*.F. 13 c++ templates template-specialization variadic-templates c++11
考虑一下代码:
#include <iostream>
template <class... Ts>
struct outer {
template <class... ITs>
struct inner {
static constexpr bool value = false;
};
template <class... ITs>
struct inner<Ts..., ITs...> {
static constexpr bool value = true;
};
};
int main() {
std::cout << outer<int, float, double>::inner<int, float, double, int>::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
代码用clang ++编译但不用g ++编译产生错误:
temp3.cc:11:11:错误:参数包参数'Ts ...'必须位于模板参数列表的末尾
Run Code Online (Sandbox Code Playgroud)struct inner<Ts..., ITs...> { ^
正如我已经在这里建立的那样,内部阶级的部分专业化应该是合法的.
编辑: 为了完整性,值得补充一点,上面代码的clang警告他可能在推导IT参数时遇到问题,但没有任何问题......
这是一个gcc bug.这是一个完全有效的部分专业化:
template <class... ITs>
struct inner<Ts..., ITs...> {
static constexpr bool value = true;
};
Run Code Online (Sandbox Code Playgroud)
推导出的模板参数包必须是最后一个,并且ITs...满足要求.但这Ts...不是一个需要在这里推断的包,它只是一个特定的参数包.
此外,gcc编译了几个等效的配方:
template <class... Ts>
struct X {
template <class... Us>
static void foo(Ts..., Us...) { }
};
int main() {
X<int>::foo(1, 'c');
}
Run Code Online (Sandbox Code Playgroud)
和:
template <class... Us>
struct A { };
template <class... Ts>
struct X {
template <class... Us>
static void foo(A<Ts..., Us...>) { }
};
int main() {
X<int>::foo(A<int, char>{});
}
Run Code Online (Sandbox Code Playgroud)
这些与您的原始示例完全相同.