шаблоны — ошибка компилятора C ++ и IBM?

Очень интересный кусок кода здесь. Я создал его с единственной целью — продемонстрировать поведение компилятора xlC.

namespace ns {
template<typename T> inline T f() { return T(); }
template<> inline double f<double>() { return 0.001; } // test specialization
};
template<typename T >
class A1 {
public: A1( const T& arg = ns::f<T>() ) {};
};
template<typename T>
class D1 {
public: D1(T t = 0) : t_(t) {};
private: T t_;
};
class my {
A1< D1<int> > a;

public: my() ;
};

//namespace ns { template<> D1<int>  f<D1<int> >() { return D1<int>(); } }

my::my() { };

void ff() {
my m;
A1<double> ad;
}

Если вы скомпилируете этот код как есть, это вызовет ошибку компиляции:

!$ xlC -c b.cpp
"b.cpp", line 7.40: 1540-0253 (S) This use of undefined class "D1<int>" is not valid.
"b.cpp", line 22.10: 1540-1205 (I) The error occurred while converting to parameter 1 of         "A1<D1<int> >::A1(const D1<int> &)".
!$ xlC -qversion
IBM XL C/C++ for AIX, V12.1 (5765-J02, 5725-C72)

!$ uname -a
AIX build25 1 6 00C8B3424C00 powerpc AIX

А теперь, если мы раскомментируем строку, начинающуюся с «// namespace» (которое является ничем иным, как специализацией шаблона для typename D1< int>, ошибка компилятора исчезает.

Компилятор GNU, похоже, не имеет проблем с этим. У кого-нибудь из вас есть идея?

PS. Конечно, проблема была обнаружена в реальном проекте, и это только упрощенный пример. В реальном проекте есть сотни классов, таких как D1< Int>. Они предполагают работать из коробки. Но для xlC я должен написать специализированные функции для каждого конкретного случая. Это очень больно …

3

Решение

xlC определенно ведет себя иначе, чем gcc для шаблонов. У меня были похожие проблемы с проектом на работе.

Попробуйте добавить определение конструктора A1. Это отсутствует.
Весьма вероятно, что xlC требует этого во время компиляции, в то время как gcc потребует этого только во время компиляции.
Увидеть Журнал GCC.

1

Другие решения

Это определенно ошибка компилятора, аргумент по умолчанию для класса A1
public: A1( const T& arg = ns::f<T>() );

Вызывает запрос на неявную реализацию D1<int> в строке 7 (до определения класса D1)

Запрос не должен был быть сделан в строке 7 (ошибка компилятора).

Более простой обходной путь состоит в том, чтобы поместить явную реализацию D1<int> сразу после
определение D1

template class D1<int>;

Другой обходной путь — избегать использования аргумента по умолчанию, вызывающего неправильное неявное создание экземпляра, путем инициализации члена данных в ctor моего

my::my() : a(ns::f< D1<int> > ()) { };

Я могу исправить это в следующем выпуске, но для исправления в V12.1 вам нужно будет открыть дефект в сервисе.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector