Friendly Access C ++ Concept

Is it possible for this code to work as I would like? That is, to allow the concept to have access to the functions of a private member?

template <typename T> concept bool Writeable() { return requires (T x,std::ostream os) { { x.Write(os) } -> void }; } template <Writeable T> void Write(std::ostream &os,const T &x) { x.Write(os); } class TT { private: void Write(std::ostream &os) const { os << "foo"; } //friend concept bool Writeable<TT>(); friend void ::Write<TT>(std::ostream &,const TT &); }; 

thanks

+7
c ++ friend c ++ - concepts c ++ 17
source share
1 answer

Not. Concepts are clearly not allowed to be friends.

n4377 7.1.7 / 2

Each definition of a concept is implicitly defined as a constexpr declaration (7.1.5). A definition of a concept should not be declared using the thread_local, inline, friend, or constexpr qualifiers, nor should a definition of a concept have associated limitations (14.10.2).

We can reduce it to this example to show that access is indeed a problem:

 template <typename T> concept bool Fooable = requires (T t) { { tf() } -> void }; struct Foo { private: void f() {} }; int main() { static_assert(Fooable<Foo>, "Fails if private"); } 

However, you can use a level of indirection, something like this:

 template <typename T> void bar(T t) { tf(); } template <typename T> concept bool FooableFriend = requires(T t) { { bar(t) } -> void }; struct Foo { private: void f() {} template<typename T> friend void bar(T t); }; int main() { static_assert(FooableFriend<Foo>, ""); } 

Live demo including your example

What works. The concepts are pretty early, so I believe that they can raise the friend restriction, since the proposals have already lifted the restrictions on C ++ 11/14 features in the past.

+3
source share

All Articles