【发布时间】:2011-10-14 14:28:01
【问题描述】:
我在 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 下编译?
提前非常感谢!
【问题讨论】:
-
SunStudio 的问题,很糟糕。查看提升源可以发现许多关于如何解决问题的想法。
-
谢谢,那我去看看提升源。
-
我在 boost 源代码中浏览了一下,在我看来,解决这个问题的最有效方法是在 Sun Studio 上使用
#ifdef:不起作用),只需将所需的东西public替换为protected或private,并删除friend语句。 -
既然 M::f() 是公开的,为什么还需要朋友声明呢?
-
出现此问题的“真实”模板有一些私有数据, ::f() 也在使用这些数据。