Привет всем.
Есть шаблоно который имеет перегруженый оператор=, при работе со встроеными типами работает нормально. но если ввести пользовательские типа string возникает неоднозначность. Как можно ее устраинть? Вот сам код шаблона:
#ifndef ARRAY_H
#define ARRAY_H
#include <iostream>
#include <assert.h>
template <class elemType>
class Array;
//template <> void Array<std::string>::init( const std::string *array1, int sz );
template <class elemType>
std::ostream& operator<<( std::ostream &, Array<elemType> & );
template <class elemType>
class Array {
friend std::ostream& operator<< <>( std::ostream &, Array<elemType> & );
public:
explicit Array( int sz = DefaultArraySize )
{ init( 0, sz ); }
Array( const elemType *ar, int sz)
{ init( ar, sz ); }
Array( const Array &iA )
{ init( iA._ia, iA._size ); }
~Array() { delete[] _ia; }
Array & operator=( const Array & );
int size() const { return _size; }
elemType& operator[]( int ix ) const
{ return _ia[ix]; }
std::ostream &print( std::ostream& os = std::cout ) const;
void grow();
void sort( int,int );
int find( elemType );
elemType min();
elemType max();
private:
void init( const elemType*, int );
void swap( int, int );
static const int DefaultArraySize = 12;
int _size;
elemType *_ia;
};
#endif
template <class elemType>
void Array<elemType>::init( const elemType *array1, int sz )
{
_size = sz;
_ia = new elemType[ _size ];
for ( int ix = 0; ix < _size; ++ix ){
if (!array1 )
_ia[ix]= 0;
else
_ia[ix] = array1[ix];
}
}
template <class elemType> Array<elemType>&
Array<elemType>::operator=( const Array<elemType>&iA )
{
if ( this != &iA ) {
delete[] _ia;
init( iA._ia, iA._size );
}
return *this;
}
template <class elemType> std::ostream&
operator<<( std::ostream &os, Array<elemType> &ar )
{
return ar.print( os );
}
template <class elemType>
std::ostream & Array<elemType>::print( std::ostream &os ) const
{
const int lineLength = 12;
os <<"( " << _size << " )< ";
for ( int ix = 0; ix < _size; ++ix )
{
if ( ix % lineLength == 0 && ix )
os << "\n\t";
os << _ia[ ix ];
// не выводить запятую за последним элементом в строке,
// а также за последним элементом массива
if ( ix % lineLength != lineLength-1 && ix != _size-1 )
os << ", ";
}
os << " >\n";
return os;
}
Добавлено форматирование — Кодт
Здравствуйте, Koop, Вы писали:
K>Привет всем.
K>Есть шаблоно который имеет перегруженый оператор=, при работе со встроеными типами работает нормально. но если ввести пользовательские типа string возникает неоднозначность. Как можно ее устраинть? Вот сам код шаблона:
K>K>#ifndef ARRAY_H
[поскипано]
K> template <class elemType> Array<elemType>&
K> Array<elemType>::operator=( const Array<elemType>&iA )
K>{
K> if ( this != &iA ) {
K> delete[] _ia;
K> init( iA._ia, iA._size );
K> }
K> return *this;
K>}
K> template <class elemType> std::ostream&
K> operator<<( std::ostream &os, Array<elemType> &ar )
K>{
K> return ar.print( os );
K>}
K>
И где и какая неоднозначность-то появляется — покажи конкретнее...
Здравствуйте, Koop, Вы писали:
K>Привет всем.
K>Есть шаблоно который имеет перегруженый оператор=, при работе со встроеными типами работает нормально. но если ввести пользовательские типа string возникает неоднозначность. Как можно ее устраинть? Вот сам код шаблона:
K>K>template <class elemType>
K> void Array<elemType>::init( const elemType *array1, int sz )
K>{
K> _size = sz;
K> _ia = new elemType[ _size ];
K> for ( int ix = 0; ix < _size; ++ix ){
K> if (!array1 )
K> _ia[ix]= 0; // проблема кроется здесь, вы присваиваете пользовательские типу int
K>
else
K> _ia[ix] = array1[ix];
K> }
K>}
K>
Здравствуйте, Koop, Вы писали:
K>template <class elemType>
K> void Array<elemType>::init( const elemType *array1, int sz )
K>{
K> _size = sz;
K> _ia = new elemType[ _size ];
K> for ( int ix = 0; ix < _size; ++ix ){
K> if (!array1 )
K> _ia[ix]= 0; // <--- вот на этой строке у тебя слетает присваивание
K> else
K> _ia[ix] = array1[ix];
K> }
K>}
Очевидно, что string::operator= не может выбрать между (char)0 и (const char*)0.
Тебе нужно инициализировать массив по умолчанию...
Во-первых, если elemType — не POD-тип (т.е. имеет нетривиальный конструктор), то new elemType[_size] уже выполнил инициализацию. Дальнейшее присваивание не нужно.
А если POD-тип, то да, там будет мусор.
Но может быть, наличие мусора некриминально (чем он хуже нулевых значений, взятых с потолка)? Тут решать тебе.
Во-вторых, присваивание "пустого" значения в общем виде записывается как _ia[ix]=elemType()
... << RSDN@Home 1.2.0 alpha rev. 655>>
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Koop, Вы писали:
К>K>>template <class elemType>
K>> void Array<elemType>::init( const elemType *array1, int sz )
K>>{
K>> _size = sz;
K>> _ia = new elemType[ _size ];
K>> for ( int ix = 0; ix < _size; ++ix ){
K>> if (!array1 )
K>> _ia[ix]= 0; // <--- вот на этой строке у тебя слетает присваивание
K>> else
K>> _ia[ix] = array1[ix];
K>> }
K>>}
К>
К>Очевидно, что string::operator= не может выбрать между (char)0 и (const char*)0.
К>Тебе нужно инициализировать массив по умолчанию...
К>Во-первых, если elemType — не POD-тип (т.е. имеет нетривиальный конструктор), то new elemType[_size] уже выполнил инициализацию. Дальнейшее присваивание не нужно.
К>А если POD-тип, то да, там будет мусор.
К>Но может быть, наличие мусора некриминально (чем он хуже нулевых значений, взятых с потолка)? Тут решать тебе.
К>Во-вторых, присваивание "пустого" значения в общем виде записывается как _ia[ix]=elemType()
Большое спасибо заработало

.