鉴于这些定义
template<class T> class foo {};
template<class T> class foo1 { static int i; };
class bar { class baz {}; };
我很惊讶地看到这个编译
template<>
class foo<bar::baz> {};
但这失败并出现错误'class bar::baz' is private
template<>
int foo1<bar::baz>::i = 42;
这种情况什么时候发生,除了公开类型之外还有其他解决方法吗?
考虑CWG #182 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#182:
某些访问检查在显式实例化时被抑制。
14.7.2 [temp.explicit] 第 8 段说 […] 令我惊讶的是,对于显式,不存在(我能找到的)类似的措辞
专业化。我认为这两起案件应该得到处理
等价于下面的例子(即,专业化
应该被允许)。
template <class T> struct C {
void f();
void g();
};
template <class T> void C<T>::f(){}
template <class T> void C<T>::g(){}
class A {
class B {};
void f();
};
template void C<A::B>::f(); // okay
template <> void C<A::B>::g(); // error - A::B inaccessible
[…]
理由(2002 年 10 月):
我们重新考虑了这一点并决定两者之间的区别
情况(显式专业化和显式实例化)是
合适的。访问规则有时会在必要时改变
允许命名某些东西,如在显式实例化中,但显式
专业化不仅需要命名实体,还需要提供
某个地方的定义。
GCC 和 Clang 确实拒绝了所示示例的最后一行,这显然是不一致的行为,对于类模板的相应显式专业化,它们不会发出错误消息:
template <class> struct T {
void g();
};
class A { class B; class C; };
template <> struct T<A::B>; // Ok
template <> void T<A::C>::g(); // Error
Demo http://coliru.stacked-crooked.com/a/683d27c05be058e8。因此,我将在这里冒险并将您在 §14.3/3 中显示的两种情况称为格式错误:
一个的名字模板参数应可在该点访问
它被用作模板参数.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)