在哪些访问控制上下文中评估了概念?

时间:2018-11-12 13:33:27

标签: c++ language-lawyer c++-concepts c++20

这个问题是对此one

的后续行动

[temp.concept]/5说:

  

未实例化概念([temp.spec])。   [注:表示概念专业化的id表达式被评估为表达式([expr.prim.id])。 [...]]

因此,由于可访问性,命名概念专长的表达式可能具有不同的值。

如果是这种情况,我想知道在哪个上下文中对表达式进行评估:

  • 概念定义的上下文;

  • 表达式的上下文;

  • 表达式的上下文是否递归应用于概念定义中出现的概念表达式?

例如,A::b2A::b2_rec的值是什么?

template<class T>
concept has_private = requires(){ &T::private_;};

template<class T>
concept has_private_rec = has_private<T>;

class B{
   int private_;
   friend class A;
   };

inline constexpr bool b1 = has_private<B>;//I expects false
inline constexpr bool b1_rec = has_private_rec<B>;//I expects false

class A{
   static constexpr bool b2 = has_private<B>; //?
   static constexpr bool b2_rec = has_private_rec<B>; //?
};

注意Clang实验概念和gcc概念TS的实现会产生b1和b1_rec的编译错误,但b2和b2_rec是正确的;

1 个答案:

答案 0 :(得分:1)

首先,让我们从requires表达式开始。 section on the behavior of a requires expression对其组件表达式的访问控制没有什么特别的要说的。同样,关于访问控制的部分没有特别说明requires表达式。特别是,[class.access]/4表示:

无论名称是从声明还是表达式中引用,访问控制都统一应用于所有名称。

鉴于此,很显然requires表达式不需要特殊的规则。如果在可以访问某个名称的上下文中使用requires表达式,则requires表达式可以访问该名称。否则,它将无法访问该名称。

那么concept自己呢?好吧,这很简单。 [temp.concept]/3告诉我们:

概念定义应出现在名称空间范围内。

因此,

concept是全局定义。他们不能成为班级成员。因此,由于他们是班级成员,他们无法访问。 friend只能指定函数或类,而concept都不能。因此concept由于是朋友而无法访问。

concept使用[temp.names]/8中定义的特殊逻辑进行评估:

如果指定模板参数满足概念的规范化约束表达式([temp.constr.constr]),则concept-id的计算结果为true。否则为false。

[temp.constr.constr]所规定的规则中没有任何内容可以给予这种评估任何特殊的访问控制。

因此,用作requires声明一部分的任何concept表达式都使用全局上下文来确定它们是否可以访问名称。也就是说,他们只能使用public接口。