Ambiguity between operator >> в шаблонном классе
От: Aleksej_A  
Дата: 20.06.06 16:54
Оценка:
Добрый день!
Есть шаблонный класс:

template<class T> class Catalog : public map<T, pair<int, int> > {
    public:
    Catalog();
    void loadFromFile(string);
...
};


И соответственно реализация метода loadFromFile()
template<class T> void Catalog<T>::loadFromFile(string filename) {
    ifstream datafile(filename.c_str());
    if (!datafile){
    throw runtime_error("Can not load data from file " + filename);
    }

    T item;
    int itemcount, itemtaken;
    while (!datafile.eof()) {
    datafile >> item; //274 строка
    datafile >> itemcount >> itemtaken;
    map<T, pair<int, int> >::insert(make_pair(item, make_pair(itemcount, itemtaken)));
    }
    datafile.close();
}



Error E2015 VideoRent.cpp 274: Ambiguity between '_STL::basic_istream<char,_STL::char_traits<char> >::operator >>(bool &)' and '_STL::basic_istream<char,_STL::char_traits<char> >::operator >>(void * &)' in function Catalog<VideoRecord *>::loadFromFile(_STL::basic_string<char,_STL::char_traits<char>,_STL::allocator<char> >)
*** 1 errors in Compile ***

Для типов данных, которые я буду хранить в этом контейнере Catalog, операторы ввода из файла разумеется описаны.
Заранее спасибо!
Re: Ambiguity between operator >> в шаблонном классе
От: Feriman  
Дата: 20.06.06 17:30
Оценка: -1
Здравствуйте, Aleksej_A, Вы писали:


A_A>Добрый день!

A_A>Есть шаблонный класс:

A_A> ...


A_A>Error E2015 VideoRent.cpp 274: Ambiguity between '_STL::basic_istream<char,_STL::char_traits<char> >::operator >>(bool &)' and '_STL::basic_istream<char,_STL::char_traits<char> >::operator >>(void * &)' in function Catalog<VideoRecord *>::loadFromFile(_STL::basic_string<char,_STL::char_traits<char>,_STL::allocator<char> >)

A_A>*** 1 errors in Compile ***

A_A>Для типов данных, которые я буду хранить в этом контейнере Catalog, операторы ввода из файла разумеется описаны.

A_A>Заранее спасибо!

Попробуй в 274 строке item привести к типу void*. Т.е.:
datafile >> (void*)item; //274 строка
--
Re[2]: Ambiguity between operator >> в шаблонном классе
От: ArtDenis Россия  
Дата: 20.06.06 18:53
Оценка:
F>Попробуй в 274 строке item привести к типу void*...

А почему не к bool?
... << RSDN@Home 1.1.4 stable rev. 510>>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re: Ambiguity between operator >> в шаблонном классе
От: ArtDenis Россия  
Дата: 20.06.06 18:53
Оценка:
Приведённого тобой кода недостаточно, чтобы выяснить причину такой ошибки
... << RSDN@Home 1.1.4 stable rev. 510>>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re: Ambiguity between operator >> в шаблонном классе
От: MuTPu4  
Дата: 20.06.06 18:58
Оценка:
Здравствуйте, Aleksej_A, Вы писали:

A_A>Добрый день!

A_A>Есть шаблонный класс:
A_A>...
A_A>Для типов данных, которые я буду хранить в этом контейнере Catalog, операторы ввода из файла разумеется описаны.
A_A>Заранее спасибо!
Воспроизвести не удалось:
#include <utility>
#include <map>
#include <fstream>
#include <stdexcept>
#include <string>

struct streamable
{
  int key_;
};

::std::ifstream &
operator>>( ::std::ifstream & s, streamable & d )
{
  s >> d.key_;
  return( s );
}

bool
operator<( streamable const & lhs, streamable const & rhs )
{
  return( lhs.key_ < rhs.key_ );
}

template< class T >
class Catalog
  : public ::std::map< T, ::std::pair<int, int> >
{
  public:

    Catalog( void )
    {}

    void loadFromFile( ::std::string filename )
    {
      ::std::ifstream datafile( filename.c_str() );
      if( !datafile )
        throw ::std::runtime_error( "Can not load data from file " + filename );

      T item;
      int itemcount, itemtaken;
      while( !datafile.eof( ) )
      {
        datafile >> item; //274 строка
        datafile >> itemcount >> itemtaken;
        this->insert( ::std::make_pair( item, ::std::make_pair( itemcount, itemtaken ) ) );
      }
    }
};


int main( void )
{
  Catalog< streamable > test;
  test.loadFromFile( "test.txt" );
}


Compiled OK: Comeau Online, Visual C++ 7.1, Intel C++ 8.1, GCC 3.42
Re: Ambiguity between operator >> в шаблонном классе
От: Кодт Россия  
Дата: 21.06.06 11:01
Оценка:
Здравствуйте, Aleksej_A, Вы писали:

Уберём STL-хлам из сообщения
A_A>Error E2015 VideoRent.cpp 274: Ambiguity between 'istream::operator >>(bool &)'
A_A> and 'istream::operator >>(void * &)'
A_A> in function Catalog<VideoRecord *>::loadFromFile(string)
A_A>*** 1 errors in Compile ***


A_A>Для типов данных, которые я буду хранить в этом контейнере Catalog, операторы ввода из файла разумеется описаны.

Очевидно, не определён istream& operator >> (istream&, VideoRecord*&)

Почему компилятор потянуло на bool& | void*& — это загадка. Вроде бы VideoRecord* ни к тому, ни к другому не приводится.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Перекуём баги на фичи!
Re[2]: Ambiguity between operator >> в шаблонном классе
От: Aleksej_A  
Дата: 21.06.06 14:03
Оценка:
Здравствуйте, Кодт, Вы писали:


A_A>>Для типов данных, которые я буду хранить в этом контейнере Catalog, операторы ввода из файла разумеется описаны.

К>Очевидно, не определён istream& operator >> (istream&, VideoRecord*&)

Немного переделал код и терерь ошибки совсем другие
В общем, ситуация такая — есть класс VideoRecord, обьектов которого нельзя создавать и наследующие VideoRecord классы VideoTape и DVD. Есть шаблонный класс Catalog, в котором будут храниться обьекты VideoTape и DVD. В обьекты VideoTape и DVD должна быть возможность ввода из файла, но набор атрибутов, которые надо из файла прочесть, для обоих классов одинаков, поэтому я описал оператор только для базового класса VideoRecord :


class VideoRecord {
...
friend ifstream& operator>> (ifstream& input, VideoRecord& record) {
    input.getline(title, sz);
    input.getline(year, sz);
    input.getline(producer, sz);
    input.getline(genre, sz);
    input.getline(country, sz);

    record.setTitle(title);
    record.setYear(atoi(year));
    record.setProducer(producer);
    record.setGenre(genre);
    record.setCountry(country);
}
...
};


В самой программе я объявляю тип шаблона так:
Catalog<DVD *> dvdCatalog;
dvdCatalog.loadFromFile("dvd_catalog.txt");

и сама функция шаблонного класса Catalog

template<class T> void Catalog<T>::loadFromFile(string filename) {
    ifstream datafile(filename.c_str());
    if (!datafile){
    throw runtime_error("Can not load data from file " + filename);
    }

    T item();
    
    int itemcount, itemtaken, stop;
    char buffer[128];
    while (!datafile.eof()) {
    datafile >> *item; //395 строка


    datafile.getline(buffer, 128);
    itemcount = atoi(buffer);
    memset(buffer, 0, 128);
    datafile.getline(buffer, 128);
    itemtaken = atoi(buffer);
    memset(buffer, 0, 128);

    map<T, pair<int, int> >::insert(make_pair(item, make_pair(itemcount, itemtaken)));
    }
    datafile.close();
}


Ошибки такие:

Error E2015 VideoRent.cpp 395: Ambiguity between '_STL::basic_istream<char,_STL::char_traits<char> >::operator >>(bool &)' and '_STL::basic_istream<char,_STL::char_traits<char> >::operator >>(void * &)' in function Catalog<DVD *>::loadFromFile(_STL::basic_string<char,_STL::char_traits<char>,_STL::allocator<char> >)
Error E2472 C:\Program Files\Borland\CBuilder6\Include\stl/_pair.h 41: Cannot declare a member function via instantiation in function Catalog<DVD *>::loadFromFile(string)
Error E2034 C:\Program Files\Borland\CBuilder6\Include\stl/_pair.h 52: Cannot convert 'DVD * (* const)()' to 'DVD *' in function pair<DVD * const,pair<int,int> >::pair(const pair<DVD *(),pair<int,int> > &)
*** 3 errors in Compile ***

Заранее спасибо.
Re[3]: Ambiguity between operator >> в шаблонном классе
От: Lorenzo_LAMAS  
Дата: 21.06.06 14:14
Оценка:
Так в данном случае T item(); — объявление функции.
Of course, the code must be complete enough to compile and link.
Re[3]: Ambiguity between operator >> в шаблонном классе
От: Кодт Россия  
Дата: 21.06.06 14:23
Оценка:
Здравствуйте, Aleksej_A, Вы писали:

A_A>Немного переделал код и терерь ошибки совсем другие


Овладевай искусством читать ошибки.
Кстати, они всё те же самые.

A_A>В общем, ситуация такая — есть класс VideoRecord, обьектов которого нельзя создавать и наследующие VideoRecord классы VideoTape и DVD. Есть шаблонный класс Catalog, в котором будут храниться обьекты VideoTape и DVD. В обьекты VideoTape и DVD должна быть возможность ввода из файла, но набор атрибутов, которые надо из файла прочесть, для обоих классов одинаков, поэтому я описал оператор только для базового класса VideoRecord :


A_A>class VideoRecord {
A_A>...
A_A>friend ifstream& operator>> (ifstream& input, VideoRecord& record) {
A_A>    input.getline(title, sz);
A_A>    input.getline(year, sz);
A_A>    input.getline(producer, sz);
A_A>    input.getline(genre, sz);
A_A>    input.getline(country, sz);

A_A>    record.setTitle(title);
A_A>    record.setYear(atoi(year));
A_A>    record.setProducer(producer);
A_A>    record.setGenre(genre);
A_A>    record.setCountry(country);
A_A>}
A_A>...
A_A>};


A_A>В самой программе я объявляю тип шаблона так:

A_A> Catalog<DVD *> dvdCatalog;
A_A> dvdCatalog.loadFromFile("dvd_catalog.txt");

A_A>и сама функция шаблонного класса Catalog


A_A>
A_A>template<class T> void Catalog<T>::loadFromFile(string filename) {
    // где T - это VideoTape* или DVD*, то есть это некий указатель
A_A>    ifstream datafile(filename.c_str());
A_A>    if (!datafile){
A_A>    throw runtime_error("Can not load data from file " + filename);
A_A>    }

A_A>    T item();
        // здесь ты объявил функцию item без параметров, возвращающую T
    
A_A>    int itemcount, itemtaken, stop;
A_A>    char buffer[128];
A_A>    while (!datafile.eof()) {
A_A>    datafile >> *item; //395 строка
        // естественно, что istream не знает, как можно вывести что-то в разыменованный указатель на функцию
        // (имя функции имеет тип указателя на функцию)

A_A>    datafile.getline(buffer, 128);
A_A>    itemcount = atoi(buffer);
A_A>    memset(buffer, 0, 128);
A_A>    datafile.getline(buffer, 128);
A_A>    itemtaken = atoi(buffer);
A_A>    memset(buffer, 0, 128);

A_A>    map<T, pair<int, int> >::insert(make_pair(item, make_pair(itemcount, itemtaken)));
        // и здесь - попытка добавить пару, у которой first - это укзатель на функцию
A_A>    }
A_A>    datafile.close();
A_A>}


A_A>Ошибки такие:


A_A>Error E2015 VideoRent.cpp 395: Ambiguity between '_STL::basic_istream<char,_STL::char_traits<char> >::operator >>(bool &)' and '_STL::basic_istream<char,_STL::char_traits<char> >::operator >>(void * &)' in function Catalog<DVD *>::loadFromFile(_STL::basic_string<char,_STL::char_traits<char>,_STL::allocator<char> >)

A_A>Error E2472 C:\Program Files\Borland\CBuilder6\Include\stl/_pair.h 41: Cannot declare a member function via instantiation in function Catalog<DVD *>::loadFromFile(string)
A_A>Error E2034 C:\Program Files\Borland\CBuilder6\Include\stl/_pair.h 52: Cannot convert 'DVD * (* const)()' to 'DVD *' in function pair<DVD * const,pair<int,int> >::pair(const pair<DVD *(),pair<int,int> > &)
A_A>*** 3 errors in Compile ***

A_A>Заранее спасибо.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Перекуём баги на фичи!
Re[4]: Ambiguity between operator >> в шаблонном классе
От: Aleksej_A  
Дата: 21.06.06 14:24
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Так в данном случае T item(); — объявление функции.


Ну вроде не объявление, у меня пустые конструкторы есть ...
Вообще, мне надо, чтобы до вызова оператора >> (в datafile >> *item объект item был уже создан. Но вот как написать аналог DVD* item = new DVD(), если T равен DVD* ?
Я пытался сделать так: T item = (*T)() и так T item = *(new T()), но по-моему обе конструкции неверны. Плюнул на все, написал для DVD и VideoTape пустые конструкторы и вызвал T item();

А как надо?
Re[5]: Ambiguity between operator >> в шаблонном классе
От: Кодт Россия  
Дата: 21.06.06 14:51
Оценка: 1 (1)
Здравствуйте, Aleksej_A, Вы писали:

A_A>Здравствуйте, Lorenzo_LAMAS, Вы писали:


L_L>>Так в данном случае T item(); — объявление функции.


A_A>Ну вроде не объявление, у меня пустые конструкторы есть ...


Таки объявление функции T item(void).

Кстати "у меня пустые конструкторы" к делу не относится, потому что T — это указатель. Конечно, пустой конструктор есть и у него тоже (определённый компилятором)...

Багфикс может выглядеть так
PointerType item = NULL;
// или
PointerType item = PointerType();
// или
ObjectType item; // вот тут твой пустой конструктор пригодится


А вообще, надо заметить:
1) Наследоваться от стандартного контейнера — это дурной тон. Лучше сделай map членом
2) Если в контейнере могут быть только указатели — то пусть шаблон сам это и делает, а не заставляет писать звёздочку в клиентском коде
template<class ObjectType>
class Catalog
{
private:
    typedef std::map<ObjectType*, std::pair<int,int> > map_type;
    map_type m_data;
public:
    // а здесь - только те операции из map, которые можно публиковать.
    // плюс свои операции
    
    // в крайнем случае, можно выдавать map наружу
    map_type& data() { return m_data; }
    map_type const& data() const { return m_data; }
};
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Перекуём баги на фичи!
Re[6]: Ambiguity between operator >> в шаблонном классе
От: Lorenzo_LAMAS  
Дата: 22.06.06 08:11
Оценка:
К>Кстати "у меня пустые конструкторы" к делу не относится, потому что T — это указатель. Конечно, пустой конструктор есть и у него тоже (определённый компилятором)...

Нету у указателя никаких конструкторов. В свое время это загнул Элджер, с тех пор так и идут слухи
Of course, the code must be complete enough to compile and link.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.