Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.88
Kravensky
 Аватар для Kravensky
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 24
02.03.2012, 05:39     Можно ли сравнивать потоки? #1
А точнее, проверять их на равенство? Скажем, допустимо ли в перегруженном операторе ввода использовать конструкцию if (stream == cout), и будет ли она корректно работать?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Luke
37 / 37 / 1
Регистрация: 21.02.2012
Сообщений: 95
02.03.2012, 13:20     Можно ли сравнивать потоки? #21
Nameless One, что? если один поток фэйл они точно будут не равны даже если одного типа.
если оба потока гуд - то вернется this дочернего класса который подставится в сравнение
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
02.03.2012, 13:25     Можно ли сравнивать потоки? #22
Luke, где гарантии, что у других компиляторов (или на другой платформе) или у новой версии MinGW будет точно такое же поведение?

Цитата Сообщение от Luke Посмотреть сообщение
если один поток фэйл они точно будут не равны даже если одного типа.
я тебе говорю, что «равенство» stream1 == stream2 не означает равенство потоков, оно означает, что stream1.fail() == stream2.fail()? Что тут непонятного?
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
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, третья — еще что-то и т.д.
Kravensky
 Аватар для Kravensky
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, соответственно.
Luke
37 / 37 / 1
Регистрация: 21.02.2012
Сообщений: 95
02.03.2012, 14:01     Можно ли сравнивать потоки? #25
Цитата Сообщение от Nameless One Посмотреть сообщение
я тебе говорю, что «равенство» stream1 == stream2 не означает равенство потоков, оно означает, что stream1.fail() == stream2.fail()? Что тут непонятного?
а что ты имеешь ввиду под равенством потоков?)
речь шла о сравнении потоков, по какому признаку они сравнивались в языке - другой вопрос.
я привел пример с this, если в НОВОМ стандарте возврат this не гарантирован значит вернется некий "другой" уникальный идентификатор, по которому и пройдет сравнение.
ну а для системы они в любом случае 2 разных потока и вряд ли язык в какой либо реализации станет противоречить этому
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
02.03.2012, 14:06     Можно ли сравнивать потоки? #26
Цитата Сообщение от Luke Посмотреть сообщение
а что ты имеешь ввиду под равенством потоков?)
Можно ли сравнивать потоки?

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

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

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

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

регистры при том, что там ты увидишь искомое значение, которое поможет тебе понять чем отличается cin от cout при их сравнении через ==
Байт
 Аватар для Байт
13974 / 8805 / 1227
Регистрация: 24.12.2010
Сообщений: 15,949
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) ...
должно работать, тк сравниваются указатели. и еслт они указывают в одно и тоже место, то и находятся там одинаковые байты...
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
02.03.2012, 14:29     Можно ли сравнивать потоки? #31
Цитата Сообщение от Luke Посмотреть сообщение
а все я понял. ты про это? это лишь предположение базирующееся на том что потоки они уникальны в системе.
регистры при том, что там ты увидишь искомое значение, которое поможет тебе понять чем отличается cin от cout при их сравнении через ==
я тебе говорю, что конкретная реализация может возвращать this, но на это надеяться нельзя, т.к. такое поведение не гарантировано. Единственной причиной того, что компилятор не считает выражение типа stream1 == stream2 (напомню, что operator == для потоков не определен) за ошибку, является тот факт, что в булевом контексте у потоков вызывается "operator unspecified-bool-type () const;", единственное предназначение которого — проверить, не случилось ли с потоком ничего плохого.
Kravensky
 Аватар для Kravensky
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 24
02.03.2012, 14:31  [ТС]     Можно ли сравнивать потоки? #32
Байт, я ж в первоначальном варианте пробовал. Но, судя по прошлым постам темы, большинство сходится в том, что так делать нельзя. И, так как я сейчас на эксперименты не настроен, предпочитаю более понятный лично мне метод - перегрузку. Но как перегрузить на конкретный параметр, я не знаю.
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
02.03.2012, 14:32     Можно ли сравнивать потоки? #33
Цитата Сообщение от Байт Посмотреть сообщение
Kravensky, А чего б тебе не попробовать такой код
И не надо никого спрашивать...
Байт, в С, естественно, сработает (на то они и указатели), в С++ — нет гарантии.
Luke
37 / 37 / 1
Регистрация: 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 Посмотреть сообщение
Байт, в С, естественно, сработает, в С++ — нет гарантии.
в с++ при сравнении указателей - те же гарантии
Kravensky
 Аватар для Kravensky
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 перегрузить? Не прибегая к шаблонам и проверке на равенство?
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
02.03.2012, 14:58     Можно ли сравнивать потоки? #36
Цитата Сообщение от Kravensky Посмотреть сообщение
Попробовал так. Компилятор ругается на двусмысленность. А посему вопрос: как можно явно указать поток cout?
С двусмысленностью часто помогает явное указание типа, попробуйте:
C++
1
stream << ( int )output_matrix.order << endl;
Luke
37 / 37 / 1
Регистрация: 21.02.2012
Сообщений: 95
02.03.2012, 14:58     Можно ли сравнивать потоки? #37
Цитата Сообщение от Kravensky Посмотреть сообщение
дык в c++ потоки не указателями реализуются, вроде. А классами.
прошу прощения а что мешает взять адрес объекта класса?
Байт
 Аватар для Байт
13974 / 8805 / 1227
Регистрация: 24.12.2010
Сообщений: 15,949
02.03.2012, 15:06     Можно ли сравнивать потоки? #38
Цитата Сообщение от Kravensky Посмотреть сообщение
дык в c++ потоки не указателями реализуются, вроде. А классами.
Ну да. А в Си - структурами. Но экземпляр потока будет указателем на некую область памяти. в Си, во всяком случае. Чем будет stream-поток в плюсах, я не разбирался. Но кажется
C++
1
2
  ofstream s; // просто область памяти в стеке
  ofstream *ss = new ofstream; // указатель на область памяти в куче (сам указатель - в стеке)
Путаница усугубляется передачей параметров по адресу, которая на самом деле есть передача указателя.
Если я не прав, пусть товарищи меня поправят.
Kravensky
 Аватар для Kravensky
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 24
02.03.2012, 15:07  [ТС]     Можно ли сравнивать потоки? #39
BRcr, не помогло, к сожалению.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.03.2012, 15:12     Можно ли сравнивать потоки?
Еще ссылки по теме:

Можно ли сравнивать строковые литералы? как правильно это сделать? C++
Как идти по строке с конца к середине и сравнивать буквы C++
C++ Почему два char нельзя сравнивать так ==?

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

Или воспользуйтесь поиском по форуму:
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
02.03.2012, 15:12     Можно ли сравнивать потоки? #40
Kravensky, если вам надо только cout и еще какой-то один поток отличать, тогда сравнение по адресу cout, как предложил Luke, является, пожалуй, простейшим вариантом.
Yandex
Объявления
02.03.2012, 15:12     Можно ли сравнивать потоки?
Ответ Создать тему
Опции темы

Текущее время: 23:05. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru