我在Sun Studio中为模板类提供模板朋友时遇到问题。使用GNU G ++(4.4.1和4.4.3)编译代码很好,但是使用Sun Studio C ++(5.9 SunOS_sparc Patch 124863-01 2007/07/25)失败了。
这是一个最小的例子:
// Forward declarations
template<class T> class M;
template<class T> void f(M<T>, M<T>);
// Define M<T>
template<class T>
class M
{
public:
void f(M<T>) { }
friend void ::f<>(M<T>, M<T>);
};
// Define global function f
template<class T>
void f(M<T> a, M<T> b)
{
a.f(b);
}
M<int> a;
当我尝试通过CC -c -o t3.o t3.cpp
编译它时,收到以下错误消息:
"t3.cpp", line 12: Warning: A friend function with template-id name must have a template declaration in the nearest namespace.
"t3.cpp", line 22: Where: While specializing "M<int>".
"t3.cpp", line 22: Where: Specialized in non-template code.
"t3.cpp", line 12: Error: Global scope has no declaration for "f".
"t3.cpp", line 22: Where: While specializing "M<int>".
"t3.cpp", line 22: Where: Specialized in non-template code.
1 Error(s) and 1 Warning(s) detected.
这是Sun Studio C ++的问题,还是无效的C ++(GCC仍然接受它并且-Wall -pedantic
没有警告)?是否有一种优雅的方式来更改代码,使其符合标准,并在GCC和Sun Studio下进行编译?
提前多多感谢!
答案 0 :(得分:3)
使用“CC:Sun C ++ 5.8 Patch 121017-13 2008/01/02”成功编译代码,将模板声明添加到朋友:
template<class T>
class M
{
...
template <class A>
friend void ::f(M<A>, M<A>);
...
};
以下不是原始问题的答案,而是那些正在寻找朋友模板类为什么导致“错误:多个声明”使用Sun CC编译器编译错误的人,只需为好友类添加前向声明,如下所示:
template <typename T> class B; //will fail without forward declaration
class A
{
private:
template <typename T> friend class B;
};
template <typename T> class B {};
答案 1 :(得分:0)
Sun的编译器确实存在一些问题,并且肯定比g ++等编译器更新。在这种情况下,问题似乎是编译器被影响全局模板函数的类弄糊涂了。
我无法找到直接解决问题的方法,但有可能的解决方法:
f
和朋友重命名为foo
允许sun编译它。如果功能不相关,这尤其有意义。M
来避免友谊。