Tôi xin lỗi nếu tiêu đề của câu hỏi này ít hữu ích hơn; Tôi không biết một cách gọn gàng để hỏi câu hỏi này mà không đưa ra các ví dụ sau:Đối số mẫu mẫu từ không gian tên khác nhau có phải là một người bạn không?
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_;
};
}
Như bạn thấy, Arg2
là một bản sao của Arg1
. Tuy nhiên, VS 2008 chỉ cho phép Arg1
được sử dụng như một mẫu đối số:
int main() {
C<Arg1> c1; // compiles ok
C<NS::Arg2> c2; // error C2248
return 0;
}
Lỗi này là 'C<Arg>::i_' : cannot access private member declared in class 'C<Arg>'
. Mọi thứ hoạt động tốt nếu i_
được đặt ở chế độ công khai, vì vậy đây có vẻ là vấn đề về tình bạn.
Điều gì khiến tuyên bố tình bạn thất bại khi đối số mẫu mẫu nằm trong một không gian tên khác?
Tôi nên thêm rằng cùng một mã cũng không biên dịch trong cả VS 2010 và VS 2012. –