C++概念,具有类似朋友的访问权限

met*_*fox 7 c++ friend c++-concepts c++17

有可能让这个代码按照我的意愿工作吗?即允许概念访问私有成员函数?

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 &);
};
Run Code Online (Sandbox Code Playgroud)

谢谢

uh *_*per 4

不可以。明确不允许概念成为朋友。

n4377 7.1.7/2

每个概念定义都隐式定义为 constexpr 声明 (7.1.5)。概念定义不应使用 thread_local、inline、friend 或 constexpr 说明符进行声明,概念定义也不应具有关联的约束 (14.10.2)。

我们可以将其简化为这个示例,以表明访问确实是问题所在:

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");
}
Run Code Online (Sandbox Code Playgroud)

但是,您可以使用一定程度的间接性,如下所示:

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>, "");
}
Run Code Online (Sandbox Code Playgroud)

结合您的示例的现场演示

这有效。概念还很早,所以我想他们可能会解除限制,friend就像提案过去解除了对 C++11/14 功能的限制一样。