8

このコードを思い通りに動作させることは可能ですか? つまり、コンセプトがプライベートメンバー機能にアクセスできるようにしますか?

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

ありがとう

4

1 に答える 1

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

ただし、次のようなレベルの間接化を使用できます。

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

あなたの例を組み込んだライブデモ

これは機能します。friend概念はかなり初期段階にあるため、過去に C++11/14 機能の制限が解除された提案があったように、将来的には制限が解除される可能性があると想像しています。

于 2016-05-18T10:40:20.413 に答える