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

2022-03-07 00:00:00 language-lawyer c++ c++20 c++-concepts

此问题是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为真;


解决方案

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

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

鉴于此,requires表达式不需要特殊规则似乎相当清楚。如果在可以访问某个名称的上下文中使用requires表达式,则requires表达式可以访问该名称。否则,它无法访问该名称。

那么concept本身又如何呢?嗯,那很简单。[temp.concept]/3告诉我们:

概念定义应出现在命名空间作用域中。

因此concept是全局定义;它们不能是类的成员。因此,由于是类成员,他们无法访问。friend只能指定函数或类,concept两者都不能。因此,aconcept由于是朋友而无法访问。

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

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

[temp.constr.constr]中规定的规则中没有为此类评估提供任何特殊访问控制的任何内容。

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

相关文章