具有类似朋友访问权限的 C++ 概念
C++ concept with friend-like access
是否可以让这段代码如我所愿地工作? IE。允许概念访问私有成员函数?
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 &);
};
谢谢
没有。明确不允许概念成为朋友。
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).
我们可以将其缩减为这个示例,以表明访问确实是问题所在:
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");
}
但是您可以使用间接级别,如下所示:
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
哪个有效。概念还很早,所以我想象他们可能会解除 friend
限制,就像过去提案解除对 C++11/14 功能的限制一样。
是否可以让这段代码如我所愿地工作? IE。允许概念访问私有成员函数?
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 &);
};
谢谢
没有。明确不允许概念成为朋友。
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).
我们可以将其缩减为这个示例,以表明访问确实是问题所在:
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");
}
但是您可以使用间接级别,如下所示:
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
哪个有效。概念还很早,所以我想象他们可能会解除 friend
限制,就像过去提案解除对 C++11/14 功能的限制一样。