内部模板的递归特化结束 class
End of recursion specialization of inner template class
考虑这个工作代码:
#include <typeinfo>
template <typename ...> struct A;
template <typename First, typename... Rest>
struct A<First, Rest...> {
static void execute() {
std::cout << typeid(First).name() << ' ';
A<Rest...>::execute();
}
};
template <>
struct A<> {
static void execute() {} // End of recursion.
};
int main() {
A<char, bool, int>::execute(); // char bool int
}
那么为什么下面的递归结尾编译不通过(错误语句在注释中提供):
#include <typeinfo>
template <typename ...> struct A;
template <typename... Ts>
struct A {
template <typename...> struct B;
template <typename...> static void execute();
};
template <typename... Ts>
template <typename First, typename... Rest>
struct A<Ts...>::B<First, Rest...> {
static void execute() {
std::cout << typeid(First).name() << ' ';
B<Rest...>::execute();
}
};
template <typename... Ts>
template <> // invalid explicit specialization before '>' token
struct A<Ts...>::B<> { // template parameters not used in partial specialization: Ts
static void execute() {} // End of recursion
};
template <typename... Ts>
template <typename... Us>
void A<Ts...>::execute() {
B<Ts..., Us...>::execute();
}
int main() {
A<char, bool, int>::execute<double, short, float>();
}
当我使用这个递归结束而不是上面的递归时它确实有效:
template <typename... Ts>
template <typename Last>
struct A<Ts...>::B<Last> {
static void execute() {std::cout << typeid(Last).name();}
};
但我只是想知道最初的尝试有什么问题。此外,我必须使用第二种方式重复 execute() 函数的主体(这当然会导致更多的维护责任)。
GCC 4.9.2 指出 A<char, bool, int>::B<>
是一个不完整的类型。但是我定义了。
[temp.expl.spec]/p15 禁止显式特化成员模板而不显式特化每个封闭模板:
A member or a member template may be nested within many enclosing class templates. In an explicit specialization for such a member, the member declaration shall be preceded by a template<>
for each enclosing class template that is explicitly specialized. [ Example:
template<class T1> class A {
template<class T2> class B {
void mf();
};
};
template<> template<> class A<int>::B<double>;
template<> template<> void A<char>::B<char>::mf();
— end example ]
例如,这段代码编译:
template <>
template <>
struct A<>::B<> {
static void execute() {} // End of recursion
};
但它不允许您使用封闭的 class 模板中的模板参数。更好的方法是在主模板中使用包扩展 "trick":
template <typename... Ts>
template <typename... Args>
struct A<Ts...>::B {
static void execute() {
using unpack = int[];
(void)unpack{((std::cout << typeid(Args).name() << ' '), 0)...};
}
};
考虑这个工作代码:
#include <typeinfo>
template <typename ...> struct A;
template <typename First, typename... Rest>
struct A<First, Rest...> {
static void execute() {
std::cout << typeid(First).name() << ' ';
A<Rest...>::execute();
}
};
template <>
struct A<> {
static void execute() {} // End of recursion.
};
int main() {
A<char, bool, int>::execute(); // char bool int
}
那么为什么下面的递归结尾编译不通过(错误语句在注释中提供):
#include <typeinfo>
template <typename ...> struct A;
template <typename... Ts>
struct A {
template <typename...> struct B;
template <typename...> static void execute();
};
template <typename... Ts>
template <typename First, typename... Rest>
struct A<Ts...>::B<First, Rest...> {
static void execute() {
std::cout << typeid(First).name() << ' ';
B<Rest...>::execute();
}
};
template <typename... Ts>
template <> // invalid explicit specialization before '>' token
struct A<Ts...>::B<> { // template parameters not used in partial specialization: Ts
static void execute() {} // End of recursion
};
template <typename... Ts>
template <typename... Us>
void A<Ts...>::execute() {
B<Ts..., Us...>::execute();
}
int main() {
A<char, bool, int>::execute<double, short, float>();
}
当我使用这个递归结束而不是上面的递归时它确实有效:
template <typename... Ts>
template <typename Last>
struct A<Ts...>::B<Last> {
static void execute() {std::cout << typeid(Last).name();}
};
但我只是想知道最初的尝试有什么问题。此外,我必须使用第二种方式重复 execute() 函数的主体(这当然会导致更多的维护责任)。
GCC 4.9.2 指出 A<char, bool, int>::B<>
是一个不完整的类型。但是我定义了。
[temp.expl.spec]/p15 禁止显式特化成员模板而不显式特化每个封闭模板:
A member or a member template may be nested within many enclosing class templates. In an explicit specialization for such a member, the member declaration shall be preceded by a
template<>
for each enclosing class template that is explicitly specialized. [ Example:template<class T1> class A { template<class T2> class B { void mf(); }; }; template<> template<> class A<int>::B<double>; template<> template<> void A<char>::B<char>::mf();
— end example ]
例如,这段代码编译:
template <>
template <>
struct A<>::B<> {
static void execute() {} // End of recursion
};
但它不允许您使用封闭的 class 模板中的模板参数。更好的方法是在主模板中使用包扩展 "trick":
template <typename... Ts>
template <typename... Args>
struct A<Ts...>::B {
static void execute() {
using unpack = int[];
(void)unpack{((std::cout << typeid(Args).name() << ' '), 0)...};
}
};