2016-05-18 4 views
7

このコードを私が望むように動作させることはできますか?私。コンセプトがプライベートメンバー機能にアクセスできるようにするには?友人のようなアクセスを伴うC++の概念

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 &); 
}; 

おかげで明示的に

答えて

3

号の概念は友達になることは許されません。

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"); 
} 

あなたはしかし、間接のレベルを使用することができ、このような何か:

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

コンセプトはかなり早いので、私は、プロポーザルが過去にC++ 11/14の機能の制限を解除したように、friendの制限を解除する可能性があることを想像しています。