шаблон друга класса шаблона не работает в Sun Studio C ++ - PullRequest
2 голосов
/ 14 октября 2011

У меня проблема с предоставлением шаблонному классу друга-шаблона в 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 ]

3 голосов
/ 31 октября 2011

Успешно скомпилировал ваш код, используя «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 {};
0 голосов
/ 28 октября 2011

Компилятор Sun действительно имеет некоторые проблемы и, безусловно, обновляется реже, чем компиляторы, такие как g ++.В этом случае проблема, как представляется, заключается в том, что компилятор смущен классом, скрывающим глобальную функцию шаблона.

Я не мог найти способ прямого решения вашей проблемы здесь, но есть возможные обходные пути:

  • Только не следите за глобальным шаблоном в вашем классе.Например, переименование глобального f и друга в foo позволяет солнцу скомпилировать его.Это особенно имеет смысл, если функции не связаны.
  • Избегайте необходимости дружбы, расширив общедоступный интерфейс до M, если это кажется подходящим.
...