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.
uh oh somebody needs a pupper
source share