【发布时间】:2021-06-10 07:04:54
【问题描述】:
假设我们有代码:
template <int Size>
struct A {
template <typename T, typename Enable = void> struct B;
template <> struct B<bool, std::enable_if_t<Size >= 1>> {};
template <> struct B<short, std::enable_if_t<Size >= 2>> {};
};
template <int Size>
struct D {
template <typename T> struct E;
template <> struct E<bool> {};
template <> struct E<short> {};
};
template <int Size>
struct F {
template <typename T> struct G {};
};
template <int Size, typename T, typename Enable = void> struct C;
template <int Size> struct C<Size, bool, std::enable_if_t<Size >= 1>> {};
template <int Size> struct C<Size, short, std::enable_if_t<Size >= 2>> {};
结构 C 和 F 在所有 CLang/GCC/MSVC 中都能很好地编译。 Struct D 在 CLang/MSVC 中编译良好,但在 GCC 中有编译错误。结构 A 不能被所有 CLang/GCC/MSVC 编译。
GCC 对 D 的错误(与 A 类似):
<source>:19:15: error: explicit specialization in non-namespace scope 'struct D<Size>'
19 | template <> struct E<bool> {};
CLang 对 A 的错误:
type_traits:2514:44: error: no type named 'type' in 'std::enable_if<false>'; 'enable_if' cannot be used to disable this declaration
using enable_if_t = typename enable_if<_Cond, _Tp>::type;
MSVC 对 A 的错误:
<source>(11): error C2938: 'std::enable_if_t<false,void>' : Failed to specialize alias template
<source>(11): note: see reference to alias template instantiation 'std::enable_if_t<false,void>' being compiled
<source>(30): note: see reference to class template instantiation 'A<1>' being compiled
<source>(11): error C2913: explicit specialization; 'A<1>::B' is not a specialization of a class template
我有几个问题:
-
在标准 C++ 中是否允许 SPECIALIZE 模板化子类?有什么限制?看起来 GCC 根本不允许,CLang/MSVC 允许,但有一定的限制。
-
是否允许有模板化的子类。如果允许,那么我该如何专攻它?也许他们允许一些类外的专业化(那么语法是什么)?
-
如果不允许专门化模板化子类,那么至少是否允许拥有完全定义的模板化子类(没有专门化)?看起来上面的 struct F 使用了完全定义的模板化子类,并且在任何地方都能很好地编译。
【问题讨论】:
标签: c++ templates subclass template-specialization