模板类的模板友在Sun Studio c++中失败

template friend of template class fails in Sun Studio C++

本文关键字:c++ 失败 Studio Sun      更新时间:2023-10-16

我在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下编译?

提前感谢!

使用"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编译器编译错误的"Error: Multiple declaration for"的人,只需为朋友类添加前向声明,就像这样:

template <typename T> class B; //will fail without forward declaration
class A
{
    private:
    template <typename T> friend class B;
};
template <typename T> class B {};

Sun的编译器确实有一些问题,而且更新的频率肯定比g++等编译器要低。在这种情况下,问题似乎是编译器被遮蔽全局模板函数的类弄糊涂了。

我没有办法直接解决你的问题,但有一些可能的变通办法:

  • 只是不要在你的类中遮蔽全局模板。例如,将全局f和好友重命名为foo允许sun编译它。如果函数不相关,这尤其有意义。
  • 如果合适的话,通过将公共接口扩展到M来避免需要友谊。