Шаблон друга класса шаблона не работает в Sun Studio C++
У меня проблема с предоставлением шаблонному классу друга-шаблона в 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 ответа
Успешно скомпилировал ваш код, используя "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 {};
Компилятор Sun, как правило, имеет некоторые проблемы и, безусловно, обновляется реже, чем компиляторы, такие как g++. В этом случае, похоже, проблема в том, что компилятор запутывается из-за класса, скрывающего глобальную функцию шаблона.
Я не мог найти способ напрямую решить вашу проблему здесь, но есть возможные обходные пути:
- Только не скрывайте глобальный шаблон в вашем классе. Переименование глобального
f
и другfoo
например, позволяет солнцу скомпилировать его. Это особенно имеет смысл, если функции не связаны. - Избегайте необходимости дружбы, расширяя общедоступный интерфейс
M
если это кажется уместным.