Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ошибка при использовании template <class T>, ошибка cannot convert STL::string to int 
V
    Опции темы
Voldemar2004
  Дата 25.9.2008, 10:54 (ссылка) |  (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Сделал класс SelectTable. Метод ReadFileToArray() - открывает текстовый файл и считывает в 
Код
unsigned long int *array
 целые числа.  Далее с помощью метода 
Код
My.ReturnElementByIndex<unsigned long int>(2, My.ReturnFirstOfArray() );
 - вывожу например 2-ой элемент массива. С этим нет проблем. 

Но когда использую тип std::string в методе 
Код
ReturnElementByIndex()
:

Код
My.ReadFileName("C:\\Name.txt");
My.ReturnElementByIndex<std::string>(0, My.ReturnFirstOfFName() );


чтобы считать из текстового файла Name.txt имена файлов, то компилятор указывает мне на ошибку в методе:

Код
// Метод возвращает элемент массива *array по индексу.
        template <class T> SelectTable::ReturnElementByIndex(unsigned long int index, T *UserArray) {
                if (index>=0 && index<n) { return UserArray[index]; }
                else return -1;
        }


в строке 

Код
                if (index>=0 && index<n) { return UserArray[index]; }
 "нельзя конвертировать STL::string в int".


Код
//---------------------------------------------------------------------------

#include <fstream>      // Потоковый ввод-вывод в файл, std::ifstream File(FileName);
#include <string>       // std::string *array

//---------------------------------------------------------------------------

class SelectTable {

private:
        // Метод подсчета количества строк в файле.
        signed long int StringCount (char* FileName);

        unsigned long int *array;

        unsigned long int n;

        std::string *FName;

public:

        // Конструктор класса.
        SelectTable (void);

        // Деструктор класса.
        ~SelectTable (void);

        // Конструктор копирования.
        SelectTable(const SelectTable &T);

        // Метод считывает весь файл в массив.
        void ReadFileToArray(char* FileName);

        // Метод возвращает элемент массива *array по индексу.
        template <class T> ReturnElementByIndex(unsigned long int index, T *UserArray);

        // Метод считывает в массив типа std::string* имена файлов,
        void ReadFileName(char* FileName);

        // Возвращает 1-ый элемент массива *array.
        unsigned long int *ReturnFirstOfArray();

        // Возвращает 1-ый элемент массива *FName.
        std::string *SelectTable::ReturnFirstOfFName();

};

//---------------------------------------------------------------------------

        // Метод подсчета количества строк в файле.
        // Функция возвращает знаковый целый тип:
        // -1 - в случае ошибки открытия файла,
        // или количество строк в файле.
        signed long int SelectTable::StringCount (char* FileName) {

        std::string str;

        // Переменная для хранения количества строк.
        signed long int String_Counter = 0;

        // Чтение файла.
        std::ifstream File(FileName);

        // Вовзратить -1, если ошибка чтения файла.
        if( File.fail() ) return -1;

            while( !File.eof() )
            {
             getline(File, str);
             String_Counter++;
            };

        return String_Counter;

        }

//---------------------------------------------------------------------------

        // Конструктор класса.
        SelectTable::SelectTable(void):n(0), array(NULL), FName(NULL)
        {
        }

//---------------------------------------------------------------------------

        // Деструктор класса.
        SelectTable::~SelectTable(void)
        {
        if(n) delete []array;
        if(FName) delete []FName;
        }

//---------------------------------------------------------------------------

        // Конструктор копирования.
        SelectTable::SelectTable(const SelectTable &T) {

                if(T.array){
                array = new unsigned long int [T.n];
                n = T.n;
                FName = T.FName;
                }
        }

//---------------------------------------------------------------------------

        // Метод считывает файл в массив типа unsigned long int* .
        void SelectTable::ReadFileToArray(char* FileName){

                // Если в файле есть хотя бы одна строка,
                // то выделить память.
                if (StringCount(FileName) > 0) {
                n=StringCount(FileName);
                array = new unsigned long int [n];
                
                        std::string str;
                        // Чтение файла
                        std::ifstream File(FileName);

                        unsigned long int i=0;

                        // Пока нет конца файла.
                        while( !File.eof() )
                        {
                                getline(File, str);
                                array[i++] = atol( str.c_str() );
                        };
                }
        }

//---------------------------------------------------------------------------

        // Метод возвращает элемент массива *array по индексу.
        template <class T> SelectTable::ReturnElementByIndex(unsigned long int index, T *UserArray) {
                if (index>=0 && index<n) { return UserArray[index]; }
                else return -1;
        }

//---------------------------------------------------------------------------

        // Метод считывает в массив типа std::string* имена файлов,
        void SelectTable::ReadFileName(char* FileName){

        std::string str;

        std::ifstream File(FileName);

                if( !File.fail() )
                {
                FName = new std::string [ StringCount(FileName) ];

                unsigned long int i=0;

                    while( !File.eof() )
                    {
                     getline(File, str);
                     FName[i++] = str;
                    };

                }
        }

//---------------------------------------------------------------------------

        // Возвращает 1-ый элемент массива *array.

        unsigned long int *SelectTable::ReturnFirstOfArray() {
        return array;
        }

//---------------------------------------------------------------------------

        // Возвращает 1-ый элемент массива *FName.

        std::string *SelectTable::ReturnFirstOfFName() {
        return FName;
        }

//---------------------------------------------------------------------------

int main() {

SelectTable My;

// Нормально работает:

My.ReadFileToArray("C:\\1.txt");
ShowMessage( My.ReturnElementByIndex<unsigned long int>(0, My.ReturnFirstOfArray() ) );


My.ReadFileName("C:\\Name.txt");
ShowMessage( My.ReturnElementByIndex<std::string>(0, My.ReturnFirstOfFName() ) );


return 0;

}
//---------------------------------------------------------------------------




Добавлено через 3 минуты и 28 секунд
В чем ошибка ?


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
vinick
Дата 25.9.2008, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 9.6.2005

Репутация: 3
Всего: 22



Код

// Метод возвращает элемент массива *array по индексу.
        template <class T> SelectTable::ReturnElementByIndex(unsigned long int index, T *UserArray) {
                if (index>=0 && index<n) { return UserArray[index]; }
                else return -1;
        }


Тип возвращаемого значения кто указывать будет? Современные компиляторы такое не пропустят, а вот некоторые старые могут решить, что по умолчанию возвращается int. Ну и вобще, у тебя получается одна и та же специализация функции может возвращать два значения - в одном случае тип Т (return UserArray[index]), а во втором случае int (return -1). Так делать нельзя.

Код

template <class T> 
Т SelectTable::ReturnElementByIndex(unsigned long int index, T *UserArray) {
                if (index>=0 && index<n) { return UserArray[index]; }
                else throw std::out_of_range();
        }


PM MAIL ICQ Jabber   Вверх
Voldemar2004
Дата 25.9.2008, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



vinick, спасибо, помогло. smile 
Код

        template <class T> T SelectTable::ReturnElementByIndex(unsigned long int index, T *UserArray) {
                if (index>=0 && index<n) { return UserArray[index]; }
                else throw std::out_of_range();
        }


теперь ругается на 
Код
else throw std::out_of_range();
 Could not find a match for 'STL::out_of_range::out_of_range()

компилятор выдает ворнинги: Function should return a value на метод ReturnElementByIndex(). Хотя значения возвращаются ? smile

Добавлено через 2 минуты и 15 секунд
Цитата(vinick @  25.9.2008,  12:35 Найти цитируемый пост)
у тебя получается одна и та же специализация функции может возвращать два значения - в одном случае тип Т (return UserArray[index]), а во втором случае int (return -1). Так делать нельзя.
Об этом я тоже хотел спросить, знал, что делал не правильно, и не знал про 
Код
throw std::out_of_range();




--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
Alek86
Дата 25.9.2008, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(Voldemar2004 @  25.9.2008,  12:15 Найти цитируемый пост)
Хотя значения возвращаются ? 

при throw не возвращаются
если ворнинг не нравится. напиши так
Код
template <class T> T SelectTable::ReturnElementByIndex(unsigned long int index, T *UserArray) {
                if (!(index>=0 && index<n))
                     throw std::out_of_range();
                 return UserArray[index];                
        }



--------------------
user posted image    user posted image
PM MAIL   Вверх
vinick
Дата 25.9.2008, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 9.6.2005

Репутация: 3
Всего: 22



Цитата(Voldemar2004 @  25.9.2008,  12:15 Найти цитируемый пост)

 Could not find a match for 'STL::out_of_range::out_of_range()


Ошибся, там надо строку с сообщением указывать.
например
Код

#include <stdexcept>
...
throw std::out_of_range("bad index");

PM MAIL ICQ Jabber   Вверх
Voldemar2004
Дата 25.9.2008, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Всем спасибо за помощь.Вот этот код:
Код
template <class T> T SelectTable::ReturnElementByIndex(unsigned long int index, T *UserArray) {
                if (!(index>=0 && index<n))
                     throw std::out_of_range();
                 return UserArray[index];                
        }


разве не тоже самое, что и:
Код
template <class T> T SelectTable::ReturnElementByIndex(unsigned long int index, T *UserArray) {
                if (index>=0 && index<n)
                 return UserArray[index];    
                throw std::out_of_range();            
        }
 ?




--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
UnrealMan
Дата 26.9.2008, 01:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(Voldemar2004 @  25.9.2008,  13:15 Найти цитируемый пост)
компилятор выдает ворнинги: Function should return a value на метод ReturnElementByIndex(). Хотя значения возвращаются ?

Что за рухлядь ты используешь в качестве компилятора?
PM MAIL   Вверх
Voldemar2004
Дата 26.9.2008, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Цитата(UnrealMan @  26.9.2008,  02:41 Найти цитируемый пост)
Что за рухлядь ты используешь в качестве компилятора?
Borland C++ 5.02, C++ Builder 6.0, MinGW Developer Studio.



--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
vinter
Дата 26.9.2008, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



UnrealMan, а что не так? VS на это бы написала, что не на все пути есть return..


--------------------
Мой блог
PM MAIL WWW   Вверх
Alek86
Дата 26.9.2008, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(Voldemar2004 @  25.9.2008,  21:09 Найти цитируемый пост)
разве не тоже самое, что и:

в моем коде не должно быть ворнинга
это чисто изменение для компилятора


--------------------
user posted image    user posted image
PM MAIL   Вверх
Voldemar2004
Дата 26.9.2008, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Цитата(Alek86 @  26.9.2008,  10:56 Найти цитируемый пост)
в моем коде не должно быть ворнингаэто чисто изменение для компилятора
Ворнинги остались.

Имхо, такое изменение кода, есть тоже самое, что и:

Код

если 10 > 5
 тогда "Да"
иначе "Нет"


Код

если не(10 > 5)
 тогда "Нет"          
иначе "Да"






Это сообщение отредактировал(а) Voldemar2004 - 26.9.2008, 10:59


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
Hroft
Дата 26.9.2008, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 20.10.2003
Где: Москва

Репутация: нет
Всего: 3



Как это остались? Безусловный ретурн последней строкой метода, какой может быть еще ворнинг?

Цитата(Voldemar2004 @  26.9.2008,  10:58 Найти цитируемый пост)
если не(10 > 5)
 тогда "Нет"          
иначе "Да"

Нет, слова "иначе" нету. Ответ "Да" всегда, когда не "Нет", а не только тогда, когда не "Нет" smile Семантика одна, а запись разная, компилятор же на запись смотрит, а не на семантику.
Такая же техника может использоваться, если нужно кинуть исключение посреди рабочего кода в Java. Если просто написать throw, то компилятор ругнется на последующие инструкции как unreachable, но если написать if (true) throw, он, хотя и нахмурится на всегда выполняющееся условие, тем не менее скомпилирует.
PM MAIL ICQ   Вверх
UnrealMan
Дата 26.9.2008, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(vinter @  26.9.2008,  10:53 Найти цитируемый пост)
UnrealMan, а что не так?

Насколько я помню, даже у VC++6.0 не было такого бреда с диагностикой. throw без соответствующего обработчика в пределах функции всегда заменяет return, а потому предупреждений такого рода в вышеприведённом коде быть не должно.

Цитата(vinter @  26.9.2008,  10:53 Найти цитируемый пост)
VS на это бы написала, что не на все пути есть return.. 

VC++8.0 ничего не пишет.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0980 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.