C++ MSVC好友函数声明错误
考虑以下代码:C++ MSVC好友函数声明错误,c++,templates,visual-c++,C++,Templates,Visual C++,考虑以下代码: #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&
#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;
}
对我来说,这看起来像一只虫子。但是,以前有没有人遇到过这样的行为?这真的是一个错误,或者可能是一个特定的错误原因?有什么快速的解决方法吗
编辑:我已经找到了一个合适的解决方法,请参阅。非常确定这是MSV的一个已知问题。您的具体问题列在中 寻找模板作为朋友。我不知道周围的工作。然而,我认为你可以让班级成为朋友。您可以将其用作解决方法。这肯定是一个bug:。当
值
被推断为好友模板函数的数组大小时,会发生此错误。下面是代码的一个简短版本,可以很好地编译。这个示例与您的示例完全相同,只是我指定了数组的大小
class my_class
{
int m_member;
template<size_t value>
friend void friend_func(int(*)[5]);
};
template<size_t value>
void friend_func(int(*)[5])
{
my_class instance;
instance.m_member = value;
}
int main()
{
int arr[5];
friend_func<5>(&arr);
}
我已经找到了一种解决方法,它既保留了功能,又能防止错误消息。其思想是使用代理函数和代理类来携带指向数组的指针及其大小。以下是解决方案:
#include <cstddef>
// Workaround class for a bug in MSVC.
// https://connect.microsoft.com/VisualStudio/feedback/details/717749
// http://stackoverflow.com/questions/15149607
template<class element_type, size_t count>
class friend_declaration_bug_workaround
{
public:
typedef element_type(*ptr_type)[count];
private:
ptr_type m_arr;
public:
explicit friend_declaration_bug_workaround(ptr_type arr)
: m_arr(arr)
{
}
ptr_type value() const
{
return m_arr;
}
};
class my_class
{
int m_member;
friend void friend_func(int*);
template<size_t value>
friend void friend_func_workaround(friend_declaration_bug_workaround<int, value>);
};
template<size_t value>
void friend_func_workaround(friend_declaration_bug_workaround<int, value> workaround)
{
my_class instance;
instance.m_member = (*workaround.value())[0];
}
void friend_func(int* arr)
{
my_class instance;
instance.m_member = *arr;
}
template<size_t value>
void friend_func(int(*arr)[value])
{
friend_declaration_bug_workaround<int, value> workaround(arr);
return friend_func_workaround(workaround);
}
int main(int argc, char* argv[])
{
int value;
friend_func(&value); // call non-templated function
int arr[5];
friend_func(&arr); // call workarounded function
return 0;
}
#包括
//MSVC中一个bug的解决方案类。
// https://connect.microsoft.com/VisualStudio/feedback/details/717749
// http://stackoverflow.com/questions/15149607
模板
类朋友\u声明\u错误\u解决方法
{
公众:
类型定义元素类型(*ptr类型)[计数];
私人:
ptr_类型m_arr;
公众:
明确的朋友声明错误解决方法(ptr类型arr)
:m_arr(arr)
{
}
ptr_类型值()常量
{
返回m_arr;
}
};
上我的课
{
国际货币联盟成员;
friend void friend_func(int*);
模板
友元无效友元功能解决方案(友元声明解决方案);
};
模板
无效好友功能解决方案(好友声明解决方案)
{
我的_类实例;
instance.m_member=(*workaround.value())[0];
}
无效朋友函数(int*arr)
{
我的_类实例;
instance.m_member=*arr;
}
模板
无效友元函数(int(*arr)[value])
{
朋友声明错误解决方法(arr);
返回friend_func_解决方案(解决方案);
}
int main(int argc,char*argv[])
{
int值;
friend_func(&value);//调用非模板函数
int-arr[5];
friend_func(&arr);//调用变通函数
返回0;
}
叮当声毫无问题地把它吃了,这可能没有什么帮助。对不起,事实并非如此。你提到的这篇文章是为MSVC6写的;我用的是MSVC11。“Templates as Friends”bug很久以前就被修复了,如果不是的话,我的开场白中的第一个重载函数会发出一个错误。谢谢你的链接!你的解决方案有效。但是,使用它时,在没有明确指定(可能不正确)大小的情况下,我丢失了强大小的数组重载。更重要的是,当出现重载时,您发布的第一段代码会产生歧义。我已经设法找到了一个更好的解决方法。只是一个建议,但您可以避免使用std::vector
或std::array
(or)进行所有这些工作。@jessegod当然,但在我的例子中,通用集合类型(适合C++11中基于范围的集合)已经由不同的重载处理,我需要普通的C数组。我明白了,不过,基于C++11范围的for可以处理普通C数组。
template <typename T>
void friend_func(T, int value)
{
my_class instance;
instance.m_member = value;
}
#include <cstddef>
// Workaround class for a bug in MSVC.
// https://connect.microsoft.com/VisualStudio/feedback/details/717749
// http://stackoverflow.com/questions/15149607
template<class element_type, size_t count>
class friend_declaration_bug_workaround
{
public:
typedef element_type(*ptr_type)[count];
private:
ptr_type m_arr;
public:
explicit friend_declaration_bug_workaround(ptr_type arr)
: m_arr(arr)
{
}
ptr_type value() const
{
return m_arr;
}
};
class my_class
{
int m_member;
friend void friend_func(int*);
template<size_t value>
friend void friend_func_workaround(friend_declaration_bug_workaround<int, value>);
};
template<size_t value>
void friend_func_workaround(friend_declaration_bug_workaround<int, value> workaround)
{
my_class instance;
instance.m_member = (*workaround.value())[0];
}
void friend_func(int* arr)
{
my_class instance;
instance.m_member = *arr;
}
template<size_t value>
void friend_func(int(*arr)[value])
{
friend_declaration_bug_workaround<int, value> workaround(arr);
return friend_func_workaround(workaround);
}
int main(int argc, char* argv[])
{
int value;
friend_func(&value); // call non-templated function
int arr[5];
friend_func(&arr); // call workarounded function
return 0;
}