Clang 接受从别名内访问数据成员
d
模板p
,而 GCC 和 MSVC 拒绝它。这应该是
允许还是不允许?标准对此有何规定?
当通过解析返回类型间接访问
d
时
模板函数q
,借助模板别名p
,
所有编译器都会拒绝该程序。这是预期的结果吗?
这是否意味着 Clang 接受这一点根本就是错误的
第一种情况(定义a::m
)?
class a {
int d;
static const int m, n;
};
template<typename T>
using p = decltype(T::d);
const int a::m = sizeof(p<a>); // clang ok, gcc nope, msvc nope
template<typename T>
auto q() -> p<T>;
const int a::n = sizeof(q<a>()); // all nope
GCC 的错误信息:
<source>: In substitution of 'template<class T> using p = decltype (T::d)
[with T = a]':
<source>:8:28: required from here
8 | const int a::m = sizeof(p<a>);
| ^
<source>:6:20: error: 'int a::d' is private within this context
6 | using p = decltype(T::d);
| ^
<source>:2:9: note: declared private here
2 | int d;
| ^
MSVC 的错误消息:
<source>(6): error C2248: 'a::d': cannot access private member declared in
class 'a'
<source>(2): note: see declaration of 'a::d'
<source>(1): note: see declaration of 'a'
<source>(6): note: the template instantiation context (the oldest one first) is
<source>(8): note: see reference to alias template instantiation 'p<a>'
being compiled
<source>(8): error C2938: 'p' : Failed to specialize alias template
Clang 的行为是一个错误。这两种用法都是不正确的。
关于检查可访问性的上下文存在悬而未决的问题(请参阅CWG 1554),但无论这里是哪一个,
d
都将无法访问,并且必须在某些上下文中的某个时刻执行检查。