No. Concepts explicitly are not allowed to be friends.
n4377 7.1.7/2
Every concept definition is implicitly defined to be a constexpr
declaration (7.1.5). A concept definition shall not be declared with
the thread_local, inline, friend, or constexpr specifiers, nor shall a
concept definition have associated constraints (14.10.2).
We can reduce it to this example to show that the access really is the problem:
template <typename T>
concept bool Fooable = requires (T t) { { t.f() } -> void };
struct Foo
{
private:
void f() {}
};
int main()
{
static_assert(Fooable<Foo>, "Fails if private");
}
You can however use a level of indirection, something like this:
template <typename T>
void bar(T t) { t.f(); }
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 incorporating your example
Which works. Concepts are pretty early, so I imagine down the line that they might lift the friend
restriction just as proposals have lifted restrictions for C++11/14 features in the past.