Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
147 views
in Technique[技术] by (71.8m points)

c++ - In which access control context are evaluated concepts?

This question is a follow up to this one

[temp.concept]/5 says:

A concept is not instantiated ([temp.spec]). [?Note: An id-expression that denotes a concept specialization is evaluated as an expression ([expr.prim.id]). [...]]

So maybe an expression that name a concept specialization can have different value because of accessibility.

If it were the case, I wonder in which context would be evaluated the expression:

  • The context of the concept definition;

  • The context of the expression;

  • The context of the expression recursively applied to concepts expression appearing in concepts definition?

For example, what could be the value for A::b2 and A::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>; //?
};

Note Clang experimental concepts and gcc concepts TS implementation produce compilation error for b1 and b1_rec, but b2 and b2_rec are true;

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First, let's start with requires expressions. The section on the behavior of a requires expression has nothing special to say about the access controls of its component expressions. Similarly, the section on access controls says nothing in particular about requires expressions. In particular, there is [class.access]/4, which says:

Access control is applied uniformly to all names, whether the names are referred to from declarations or expressions.

Given this, it seems quite clear that requires expressions don't need special rules. If you use a requires expression in a context which has access to some name, then the requires expression has access to that name. Otherwise, it cannot access the name.

So what of concepts themselves? Well, that's simple. [temp.concept]/3 tells us:

A concept-definition shall appear at namespace scope.

concepts are therefore global definitions; they can't be members of a class. So they cannot have access due to being a class member. friend can only specify functions or classes, and concepts are neither. So a concept cannot have access due to being a friend.

concepts are evaluated using special logic, defined in [temp.names]/8:

A concept-id evaluates to true if the concept's normalized constraint-expression is satisfied ([temp.constr.constr]) by the specified template arguments and false otherwise.

There is nothing in the rules laid down in [temp.constr.constr] which gives such evaluation any special access controls.

Therefore, any requires expressions used as part of a concept declaration use the global context for determining whether they can access names. That is, they can only ever use public interfaces.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...