具有类似朋友访问权限的C ++概念 [英] C++ concept with friend-like access
问题描述
是否可以根据需要使此代码正常工作?即允许该概念访问私有成员函数?
template< typename T>
概念bool Writeable()
{返回要求(T x,std :: ostream os){{x.Write(os)}->无效}; }
模板< Writeable T>
void Write(std :: ostream& os,const T& x){x.Write(os); }
类TT
{
私有:
void Write(std :: ostream& os)const {os< foo; }
//朋友概念bool Writeable< TT>();
朋友void :: Write< TT>(std :: ostream&,const TT&);
};
谢谢
否明确地不允许概念成为朋友。
n4377 7.1.7 / 2
每个概念定义都隐式定义为是constexpr
声明(7.1.5)。概念定义不得与
的thread_local,内联,朋友或constexpr声明符一起声明,
概念定义也不应具有关联的约束(14.10.2)。
我们可以将其简化为以下示例,以表明访问确实是问题所在:
模板< typename T>
concept bool Fooable = require(T t){{t.f()}->无效};
结构Foo
{
private:
void f(){}
};
int main()
{
static_assert(Fooable< Foo>如果私有则失败);
}
但是,您可以使用一定程度的间接访问,例如:
模板< typename T>
void bar(T t){t.f(); }
模板< typename T>
concept bool FooableFriend = require(T t){{bar(t)}->无效};
结构Foo
{
私人:
void f(){}
template< typename T>
个朋友的空棒(T t);
};
int main()
{
static_assert(FooableFriend< Foo> ;,);
}
这是可行的。概念还为时过早,因此我可以想象它们可能会取消 friend
限制,就像过去的提案取消了对C ++ 11/14功能的限制一样。 / p>
Is it possible to make this code work as I'd like? I.e. to allow the concept to have access to a private member funcion?
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
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.
这篇关于具有类似朋友访问权限的C ++概念的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!