[温度规格]/6通过实现添加到 C++20P0692R1 (专业化访问检查) [emphasis mine]:
[温度规格]/6常用的访问检查规则不适用于声明中的名称显式实例化或明确的专业化,但出现在函数体、默认参数、基本子句、成员规范、枚举器列表或静态数据成员或变量模板初始值设定项中的名称除外。 [注:特别是,模板参数和名字在函数声明符中使用(包括参数类型、返回类型和异常规范)可能是私有类型或通常无法访问的对象。 ——尾注]
事实上,从 C++20 开始,这将使以下程序格式良好:
class A { class B {}; };
template<typename T> void foo() {};
template<> void foo<A::B>() {}
int main() {}
然而,海湾合作委员会(头 11.0.0 20201121; DEMO) 和 铿锵 (头 12.0.0; DEMO)拒绝上面的程序(对于-std=c++20
/-std=c++2a
),引用私人访问违规
GCC:
'class A::B' is private within this context
Clang:
error: 'B' is a private member of 'A'
GCC 列出已实施的 P0692R1:
而 Clang 将其 P0692R1 的实现列为Partial:
- Clang 中的 C++ 支持:C++20 实现状态
Question
- 这里 C++20 中的正确行为是什么,上面的程序是否格式良好(GCC bug / Clang 未完全实现)或者 GCC 和 Clang 是否正确拒绝它?
这里 C++20 中的正确行为是什么,上面的程序是否格式良好(GCC bug / Clang 未完全实现)或者 GCC 和 Clang 是否正确拒绝它?
正如OP中已经引用的那样,[temp.spec]/6支持此功能,并且该程序格式良好。特别是,下面的所有片段 (A) 到 (D) 都是格式正确的:
// (A)
class A { class B {}; };
template<typename T> struct S {};
template<> struct S<A::B> {};
// (B)
class A { class B {}; };
template<typename T> void foo() {};
template<> void foo<A::B>() {}
// (C)
class A { class B {}; };
template<typename T>
constexpr bool v = false;
template<>
constexpr bool v<A::B> = true;
// (D)
class A { class B {}; };
template<typename T, typename U> struct S {};
template<typename U> struct S<A::B, U> {};
template<typename T> struct S<T, A::B> {};
GCC is wrong to reject (B) and (C) (correctly accepts (A) and (D)), and Clang is wrong(1) to reject (B) through (D) (correctly accepts (A)).
错误报告:
- 海湾合作委员会(已确认):[C++20][P0692R1] 函数和变量模板的显式特化声明不会放弃访问检查
- Clang: [P0692R1] 函数和变量模板的显式特化声明不会免除访问检查
(1) Note that Clang (as highlighted in the OP) has marked the implementation status for P0692R1 as "Partial", so this may not be a Clang bug but rather a feature yet to be implemented C++2a/C++20.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)