Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.84/25: Рейтинг темы: голосов - 25, средняя оценка - 4.84
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 24
1

Можно ли сравнивать потоки?

02.03.2012, 05:39. Показов 5194. Ответов 41
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
А точнее, проверять их на равенство? Скажем, допустимо ли в перегруженном операторе ввода использовать конструкцию if (stream == cout), и будет ли она корректно работать?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.03.2012, 05:39
Ответы с готовыми решениями:

Можно ли сравнивать строковые литералы? как правильно это сделать?
надо сравнить введенный строковый литерал с одним из доступных. int main() { setlocale(0,""); ...

Как можно сравнивать в структуре числа и выводить на экран по возрастанию, если структура находится в файле?
Как можно сравнивать в структуре числа и выводить на экран по возрастанию, если структура находится...

О потоках std::thread: можно ли вложить потоки друг в друга и можно ли создать динамический массив потоков?
1) Могу ли я вложить потоки друг в друга? 2) Могу ли я создать динамический массив потоков,...

Switch. Можно ли сравнивать строки?
switch (expression) { case label : statementlist ... default : ...

41
40 / 40 / 7
Регистрация: 21.02.2012
Сообщений: 95
02.03.2012, 13:20 21
Author24 — интернет-сервис помощи студентам
Nameless One, что? если один поток фэйл они точно будут не равны даже если одного типа.
если оба потока гуд - то вернется this дочернего класса который подставится в сравнение
0
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
02.03.2012, 13:25 22
Luke, где гарантии, что у других компиляторов (или на другой платформе) или у новой версии MinGW будет точно такое же поведение?

Цитата Сообщение от Luke Посмотреть сообщение
если один поток фэйл они точно будут не равны даже если одного типа.
я тебе говорю, что «равенство» stream1 == stream2 не означает равенство потоков, оно означает, что stream1.fail() == stream2.fail()? Что тут непонятного?
0
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
02.03.2012, 13:28 23
Вот тебе пример:
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <fstream>
 
#define SHOW(EXPR) std::cout << #EXPR ": " << std::boolalpha << (EXPR) << std::endl
 
int main(void)
{
    std::ifstream stream1("non_existing_file_1"), stream2("non_existing_file_2");
 
    SHOW(stream1 == stream2);
}
Запусти этот код и посмотри, чему он равен (non_existing_file_1, non_existing_file_2 — это несуществующие файлы)

Ну и еще раз цитата из стандарта:
Цитата Сообщение от Nameless One Посмотреть сообщение
One possible implementation choice for this type is pointer-to-member. — end note
обрати внимание на фразу "one possible". Эта значит, что конкретная реализация может возвращать (void*) this, другая — (void*) 100500, третья — еще что-то и т.д.
0
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 24
02.03.2012, 13:49  [ТС] 24
А нельзя перегружать с ostream если консоль и ofstream при выводе в файл ?
Попробовал так. Компилятор ругается на двусмысленность. А посему вопрос: как можно явно указать поток cout?

Текущий вариант функций:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/* Вывод квадратной матрицы */
ostream &operator<< (ostream &stream, square_matrix output_matrix)
{
    for (int i = 0; i <= output_matrix.order - 1; i++)
    {
        stream << right << resetiosflags (ios::left) << setw (3) << "||";
        
        for (int j = 0; j <= output_matrix.order - 1; j++)
            stream << right << resetiosflags (ios::left) << setw (3) << output_matrix.coefficents_set [i] [j];
 
        stream << right << resetiosflags (ios::left) << setw (3) << "||" << endl;
    }
 
    stream << endl;
    
    return stream;
}
 
/* Вывод квадратной матрицы в файл */
ofstream &operator<< (ofstream &stream, square_matrix output_matrix)
{
    stream << output_matrix.order << endl;
    
    for (int i = 0; i <= output_matrix.order -1; i++)
        for (int j = 0; j <= output_matrix.order - 1; j++)
            stream << right << resetiosflags (ios::left) << setw (3) << output_matrix.coefficents_set [i] [j];
    
    stream << endl;
    
    return stream;
}
 
/* Ввод квадратной матрицы */
istream &operator>> (istream &stream, square_matrix &input_matrix)
{
    for (int i = 0; i <= input_matrix.order - 1; i++)
        for (int j = 0; j <= input_matrix.order - 1; j++)
        {
            cout << "Введите элемент [" << i + 1 << "] [" << j + 1 << "]: ";
            stream >> input_matrix.coefficents_set [i] [j];
        }
    
    return stream;
}
 
/* Ввод квадратной матрицы из файла */
ifstream &operator>> (ifstream &stream, square_matrix &input_matrix)
{
    int x;
    
    stream >> x;
    
    if (x == input_matrix.order)
        for (int i = 0; i <= input_matrix.order - 1; i++)
            for (int j = 0; j <= input_matrix.order - 1; j++)
                stream >> input_matrix.coefficents_set [i] [j];
    else
    {
        cout << "Матрицу из этого потока записать не удалось." << endl;
        cout << "Не совпадают порядки" << endl;
    }
    
    return stream;
}
Вывод компилятора:
Код
kravensky@kravensky-desktop ~ $ g++ -c -o demo.o demo_program.cpp
In file included from demo_program.cpp:3:0:
function.cpp: In function ‘std::ofstream& operator<<(std::ofstream&, square_matrix)’:
function.cpp:58:26: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
/usr/include/c++/4.5/bits/ostream.tcc:105:5: note: candidate 1: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
function.cpp:56:11: note: candidate 2: std::ofstream& operator<<(std::ofstream&, square_matrix)
Строка 58, это строка 22 в приведённом выше коде. Строка 56 - строка 20, соответственно.
0
40 / 40 / 7
Регистрация: 21.02.2012
Сообщений: 95
02.03.2012, 14:01 25
Цитата Сообщение от Nameless One Посмотреть сообщение
я тебе говорю, что «равенство» stream1 == stream2 не означает равенство потоков, оно означает, что stream1.fail() == stream2.fail()? Что тут непонятного?
а что ты имеешь ввиду под равенством потоков?)
речь шла о сравнении потоков, по какому признаку они сравнивались в языке - другой вопрос.
я привел пример с this, если в НОВОМ стандарте возврат this не гарантирован значит вернется некий "другой" уникальный идентификатор, по которому и пройдет сравнение.
ну а для системы они в любом случае 2 разных потока и вряд ли язык в какой либо реализации станет противоречить этому
0
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
02.03.2012, 14:06 26
Цитата Сообщение от Luke Посмотреть сообщение
а что ты имеешь ввиду под равенством потоков?)
https://www.cyberforum.ru/post2545662.html

Цитата Сообщение от Luke Посмотреть сообщение
я привел пример с this, если в НОВОМ стандарте возврат this не гарантирован значит вернется некий "другой" уникальный идентификатор, по которому и пройдет сравнение.
где это ты вычитал про «уникальность идентификатора»? Я еще раз повторю, если в некоторой реализации в булевом контексте будет всегда возвращаться (void*) 100500 вообще для всех незафейленных потоков, то это поведение уже будет соответствовать стандарту
0
40 / 40 / 7
Регистрация: 21.02.2012
Сообщений: 95
02.03.2012, 14:13 27
Nameless One,
Можно ли сравнивать потоки?
ответ можно.
про уникальность идентификатора потока..ну например в API твоей системы.

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

проведи тест. посмотри что в регистрах при сравнениях будет
0
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
02.03.2012, 14:17 28
Цитата Сообщение от Luke Посмотреть сообщение
а тебя послушать так язык с его библиотекой будет противоречить устройству той системы на которой будет запускаться, давая идентичные идентификаторы для разных потоков
еще раз, скажи, где ты вычитал, что "operator void*unspecified-bool-type () const;" возвращает «уникальный идентификатор»? Можешь ссылку дать, а то мне тоже интересно?

Цитата Сообщение от Luke Посмотреть сообщение
проведи тест. посмотри что в регистрах при сравнениях будет
при чем тут регистры вообще?
0
40 / 40 / 7
Регистрация: 21.02.2012
Сообщений: 95
02.03.2012, 14:20 29
Цитата Сообщение от Luke Посмотреть сообщение
значит вернется некий "другой" уникальный идентификатор,
а все я понял. ты про это? это лишь предположение базирующееся на том что потоки они уникальны в системе, а так же на том
что в "старом" стандарте при операции сравнения дергался operator void*(), возвращавший либо 0 либо this

регистры при том, что там ты увидишь искомое значение, которое поможет тебе понять чем отличается cin от cout при их сравнении через ==
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
02.03.2012, 14:20 30
Kravensky, А чего б тебе не попробовать такой код
C++
1
2
3
4
5
6
7
8
9
10
F(ofstream s)
{
  if (s==cout) cout<<"Egal";
  else            cout<<"No Egal";
}
main()
{  ofsteam ss;
  F(cout);
  F(ss);
}
И не надо никого спрашивать...
Вообще, если б это был просто Си, я бы ответил ДА.
C
1
2
 F(FILE *f)
  if ( f==stdout) ...
должно работать, тк сравниваются указатели. и еслт они указывают в одно и тоже место, то и находятся там одинаковые байты...
0
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
02.03.2012, 14:29 31
Цитата Сообщение от Luke Посмотреть сообщение
а все я понял. ты про это? это лишь предположение базирующееся на том что потоки они уникальны в системе.
регистры при том, что там ты увидишь искомое значение, которое поможет тебе понять чем отличается cin от cout при их сравнении через ==
я тебе говорю, что конкретная реализация может возвращать this, но на это надеяться нельзя, т.к. такое поведение не гарантировано. Единственной причиной того, что компилятор не считает выражение типа stream1 == stream2 (напомню, что operator == для потоков не определен) за ошибку, является тот факт, что в булевом контексте у потоков вызывается "operator unspecified-bool-type () const;", единственное предназначение которого — проверить, не случилось ли с потоком ничего плохого.
1
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 24
02.03.2012, 14:31  [ТС] 32
Байт, я ж в первоначальном варианте пробовал. Но, судя по прошлым постам темы, большинство сходится в том, что так делать нельзя. И, так как я сейчас на эксперименты не настроен, предпочитаю более понятный лично мне метод - перегрузку. Но как перегрузить на конкретный параметр, я не знаю.
0
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
02.03.2012, 14:32 33
Цитата Сообщение от Байт Посмотреть сообщение
Kravensky, А чего б тебе не попробовать такой код
И не надо никого спрашивать...
Байт, в С, естественно, сработает (на то они и указатели), в С++ — нет гарантии.
1
40 / 40 / 7
Регистрация: 21.02.2012
Сообщений: 95
02.03.2012, 14:44 34
Kravensky,

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void compare (basic_ostream<char>& os)//это и есть перегрузка. все потоки вывода наследуются от него.
{
    
    if(&os==&cout)//сравнивай адреса вот и все.cout глобален его адрес не изменится
    {
        os<<"COUT";
    }
    else
    {
 
        os<<"FILE";//если на входе не cout а например ofstream 
    }
    
}
Добавлено через 1 минуту
Цитата Сообщение от Nameless One Посмотреть сообщение
Байт, в С, естественно, сработает, в С++ — нет гарантии.
в с++ при сравнении указателей - те же гарантии
2
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 24
02.03.2012, 14:54  [ТС] 35
Luke, дык в c++ потоки не указателями реализуются, вроде. А классами.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ostream &operator<< (ostream &stream, square_matrix output_matrix)
{
    for (int i = 0; i <= output_matrix.order - 1; i++)
    {
        stream << right << resetiosflags (ios::left) << setw (3) << "||";
        
        for (int j = 0; j <= output_matrix.order - 1; j++)
            stream << right << resetiosflags (ios::left) << setw (3) << output_matrix.coefficents_set [i] [j];
 
        stream << right << resetiosflags (ios::left) << setw (3) << "||" << endl;
    }
 
    stream << endl;
    
    return stream;
}
Эту функцию как исключительно для cout перегрузить? Не прибегая к шаблонам и проверке на равенство?
0
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
02.03.2012, 14:58 36
Цитата Сообщение от Kravensky Посмотреть сообщение
Попробовал так. Компилятор ругается на двусмысленность. А посему вопрос: как можно явно указать поток cout?
С двусмысленностью часто помогает явное указание типа, попробуйте:
C++
1
stream << ( int )output_matrix.order << endl;
1
40 / 40 / 7
Регистрация: 21.02.2012
Сообщений: 95
02.03.2012, 14:58 37
Цитата Сообщение от Kravensky Посмотреть сообщение
дык в c++ потоки не указателями реализуются, вроде. А классами.
прошу прощения а что мешает взять адрес объекта класса?
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
02.03.2012, 15:06 38
Цитата Сообщение от Kravensky Посмотреть сообщение
дык в c++ потоки не указателями реализуются, вроде. А классами.
Ну да. А в Си - структурами. Но экземпляр потока будет указателем на некую область памяти. в Си, во всяком случае. Чем будет stream-поток в плюсах, я не разбирался. Но кажется
C++
1
2
  ofstream s; // просто область памяти в стеке
  ofstream *ss = new ofstream; // указатель на область памяти в куче (сам указатель - в стеке)
Путаница усугубляется передачей параметров по адресу, которая на самом деле есть передача указателя.
Если я не прав, пусть товарищи меня поправят.
1
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 24
02.03.2012, 15:07  [ТС] 39
BRcr, не помогло, к сожалению.
0
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
02.03.2012, 15:12 40
Kravensky, если вам надо только cout и еще какой-то один поток отличать, тогда сравнение по адресу cout, как предложил Luke, является, пожалуй, простейшим вариантом.
1
02.03.2012, 15:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.03.2012, 15:12
Помогаю со студенческими работами здесь

Как можно сравнивать 2 файла по названию
Подскажите,как можно сравнивать 2 фаила по названию.Спасибо

Можно ли сравнивать два метода, вычисляющих площадь?
Здравствуйте. Подскажите, пожалуйста. У меня создан метод который считает площадь треугольника (В...

Откуда взять ряд с которым можно сравнивать?
часто при исследовании сходимости ряда пишут сравним с таким то рядом,который сходится.откуда такие...

Как можно сравнивать поля двух подчиненных форм?
У меня есть две подчиненные формы, расположенные рядышком. В одной в поле со списком выбирается...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru