2

我在 Sun Studio 中为模板类提供模板朋友时遇到问题。该代码可以使用 GNU G++(4.4.1 和 4.4.3)正常编译,但使用 Sun Studio C++(5.9 SunOS_sparc 补丁 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 下编译?

提前非常感谢!

4

2 回答 2

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 {};
于 2011-10-31T13:58:37.583 回答
0

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

我无法找到直接解决您的问题的方法,但有可能的解决方法:

  • 只是不要在您的班级中隐藏全局模板。例如,将全局f和朋友重命名foo为允许 sun 编译它。如果功能不相关,这尤其有意义。
  • M如果合适的话,可以通过扩展公共接口来避免友谊的需要。
于 2011-10-28T14:20:28.480 回答