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

时间:2011-10-14 14:28:01

标签: c++ sunstudio

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

提前多多感谢!

2 个答案:

答案 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来避免友谊。