5

この質問のタイトルが役に立たない場合はお詫び申し上げます。次の例を挙げずに、この質問をする簡潔な方法がわかりません。

template <template <class> class Arg>
class C {
    typedef C<Arg> type;
    friend class Arg<type>;
  public:
    C() {
        a_.set(this);
    }
  private:
    int i_;
    Arg<type> a_;
};

template <class Type>
class Arg1 {
  public:
    void set(Type* t) {
        t_ = t;
        t_->i_ = 1;
    }
  private:
    Type* t_;
};

namespace NS {

    template <class Type>
    class Arg2 {
      public:
        void set(Type* t) {
            t_ = t;
            t_->i_ = 2;
        }
      private:
        Type* t_;
    };

}

ご覧のとおりArg2、 のコピーですArg1。ただし、VS 2008 ではArg1テンプレート引数としてのみ使用できます。

int main() {
    C<Arg1> c1; // compiles ok
    C<NS::Arg2> c2; // error C2248

    return 0;
}

エラーは'C<Arg>::i_' : cannot access private member declared in class 'C<Arg>'です。i_公開すればすべてうまくいくので、これは友情の問題のようです.

テンプレート テンプレート引数が別の名前空間にある場合、友情宣言が失敗する原因は何ですか?

4

1 に答える 1

0

名前空間のメンバーシップは、友情の資格には影響しません。これはコンパイラのバグです。

friendただし、namespace相互に作用する言語機能であるため、バグが発生しても特に驚くべきことではありません。おそらく、実際には、囲んでいる名前空間::Arg2<type>.

于 2013-02-26T03:57:09.000 に答える