考虑以下代码:
#include <cstddef>
template<size_t value> class dummy { };
class my_class
{
int m_member;
// Overload 1
template<size_t value>
friend void friend_func(dummy<value>*);
// Overload 2
template<size_t value>
friend void friend_func(int(*)[value]);
};
// Overload 1
template<size_t value>
void friend_func(dummy<value>*)
{
my_class instance;
instance.m_member = value;
}
// Overload 2
template<size_t value>
void friend_func(int(*)[value])
{
my_class instance;
instance.m_member = value;
}
int main(int argc, char* argv[])
{
dummy<5> d;
friend_func(&d); // call Overload 1
int arr[5];
friend_func(&arr); // call Overload 2 - error in MSVC!
return 0;
}
如您所见,这两个函数之间的唯一区别是第二个函数使用指向value
int
s 而不是dummy<value>
. 此代码在 GCC($ gcc-4.7.2 test.cpp)和 Clang(感谢WhozCraig)中编译得很好,但在 MSVC 中抛出以下错误(我在 2012 年测试过):
1>d:\path\to.cpp(32): error C2248: 'my_class::m_member' : cannot access private member declared in class 'my_class'
1> d:\path\to.cpp(8) : see declaration of 'my_class::m_member'
1> d:\path\to.cpp(7) : see declaration of 'my_class'
1> d:\path\to.cpp(40) : see reference to function template instantiation 'void friend_func<5>(int (*)[5])' being compiled
对我来说,这看起来像一个错误。但是,有没有人遇到过这样的行为?这真的是一个错误,还是错误有特定原因?有什么快速的解决方法吗?
编辑:我已经找到了合适的解决方法,请参阅下面的答案。