Странные ошибки из-за STL
От: Аноним  
Дата: 18.09.02 15:36
Оценка:
Hi, All

Посмотрите на следующий код:

#include <iostream>
#include <vector>
using namespace std;

class A
{
public:
    friend std::ostream& operator<< (std::ostream& os, const A& a);
    friend bool operator < (A&, A&);
private:
    int m_i;
};


bool operator < (A& a1, A& a2)
{
    return (a1.m_i < a2.m_i);
}


template <class T>
std::ostream& operator<< (std::ostream& os, const A<T>& a)
{
    os << a.m_i;
    return os;
}


VC++ компилятор выдает ошибку: "error C2248: 'm_i' : cannot access private member declared in class 'A'".
Такое ощущение, что он не понял, что они — друзья. Если же убрать директиву "using namespace std;", то все работает замечательно. Следовательно, это из-за STL. Например, на operator+ компилер выдаст INTERNAL COMPILER ERROR. У меня не было времени покопаться в заголовниках STL, чтобы понять причину таких странных ошибок, но даже если там происходит какая-то колизия имен, то все-равно ошибки должны быть другого сорта (ну например "already declared" или "types mismatch").

Не подскажите причину такого поведения?
Re: Странные ошибки из-за STL
От: Bell Россия  
Дата: 18.09.02 15:57
Оценка:
Здравствуйте Аноним, Вы писали:

А>Не подскажите причину такого поведения?


Насколько я понял, глядя на
std::ostream& operator<< (std::ostream& os, const A<T>& a);

класс A — шаблонный
Тогда быть может код должен выглядеть так?

template <class T>
class A
{
public:
   friend std::ostream& operator<< (std::ostream& os, const A<T>& a);
   friend bool operator < (A<T>&, A<T>&);
private:
    
   int m_i;
};

template <class T>
bool operator < (A<T>& a1, A<T>& a2)
{
    return (a1.m_i < a2.m_i);
}

template <class T>
std::ostream& operator<< (std::ostream& os, const A<T>& a)
{
    os << a.m_i;
    return os;
}
Любите книгу — источник знаний (с) М.Горький
Re: Странные ошибки из-за STL
От: GYB  
Дата: 18.09.02 16:24
Оценка:
А>VC++ компилятор выдает ошибку: "error C2248: 'm_i' : cannot access private member declared in class 'A'".
А>Такое ощущение, что он не понял, что они — друзья. Если же убрать директиву "using namespace std;", то все работает замечательно. Следовательно, это из-за STL. Например, на operator+ компилер выдаст INTERNAL COMPILER ERROR. У меня не было времени покопаться в заголовниках STL, чтобы понять причину таких странных ошибок, но даже если там происходит какая-то колизия имен, то все-равно ошибки должны быть другого сорта (ну например "already declared" или "types mismatch").

А>Не подскажите причину такого поведения?


В том виде как было у меня даже компилироваться не стало

Но вот так вот работает всё

#include <iostream>
#include <vector>
using namespace std;

class A
{
public:
    friend std::ostream& operator<< (std::ostream& os, const A& a);
    friend bool operator < (A&, A&);
    void SetI ( int i ) { m_i = i; }
private:
    int m_i;
};


bool operator < (A& a1, A& a2)
{
    return (a1.m_i < a2.m_i);
}

std::ostream& operator<< (std::ostream& os, const A& a)
{
    os << a.m_i;
    return os;
}

int main() {
  A a1, a2;

  a1.SetI( 10 );
  a2.SetI( 15 );

  if ( a1 < a2 ) {
    cout << "a1<a2\n";
  }
  else cout << "a1>=a2";

  cout << "a1.m_i = " << a1 << "\n"
       << "a2.m_i = " << a2 << "\n";

  return 0;
}
Re: Странные ошибки из-за STL
От: Андрей Тарасевич Беларусь  
Дата: 18.09.02 17:52
Оценка:
Здравствуйте Аноним, Вы писали:

А>Посмотрите на следующий код:


А>
А>#include <iostream>
А>#include <vector>
А>using namespace std;

А>class A
А>{
А>public:
А>    friend std::ostream& operator<< (std::ostream& os, const A& a);
А>    friend bool operator < (A&, A&);
А>private:
А>    int m_i;
А>};

А>
А>bool operator < (A& a1, A& a2)
А>{
А>    return (a1.m_i < a2.m_i);
А>}

А>
А>template <class T>
А>std::ostream& operator<< (std::ostream& os, const A<T>& a)
А>{
А>    os << a.m_i;
А>    return os;
А>}

А>


А>VC++ компилятор выдает ошибку: "error C2248: 'm_i' : cannot access private member declared in class 'A'".

А>Такое ощущение, что он не понял, что они — друзья.

А почему он должен был это понять? Шаблонная функция 'operator<<' в твоем примере другом класса 'A' не является. Неудивительно, что компилятор ругается не ее попытки доступиться к 'm_i'.

А>Если же убрать директиву "using namespace std;", то все работает замечательно.


"Работать замечательно" это никак не может. Этот код не должен компилироваться ни с 'using namespace std', ни без. Если он у тебя компилируется, то это действительно глюк компилятора.
Best regards,
Андрей Тарасевич
Re[2]: Странные ошибки из-за STL
От: Аноним  
Дата: 19.09.02 06:32
Оценка:
Да да я извиняюсь. Просто я сначала писал шаблонный класс — не сработало, я подумал, что дело в шаблонах (VC++ не совсем хорошо с ними дружит) и уже начал писать вопрос в конфу, а потом обнаружил, что и без шаблонов не прет, а operator<< просто забыл переписать нормально. Короче вот точный код:

#include <iostream>
#include <vector>
using namespace std;

class A
{
public:
    friend std::ostream& operator<< (std::ostream& os, const A& a);
    friend bool operator < (A&, A&);
private:
    int m_i;
};


bool operator < (A& a1, A& a2)
{
    return (a1.m_i < a2.m_i);
}


std::ostream& operator<< (std::ostream& os, const A& a)
{
    os << a.m_i;
    return os;
}

void main()
{
}


И я по прежнему утверждаю, что VC++ выдает "error C2248: 'm_i' : cannot access private member declared in class 'A'". Но если я убираю "using namespace std;", то все компилиться без ошибок.
Далее хочу сказать, что operator<< и operator< я выбрал совершенно случайно, без всякого умысла, чисто для теста. И если, например, объявить (даже определять не надо) operator+ то компилер выдаст "fatal error C1001: INTERNAL COMPILER ERROR".
Re[2]: Странные ошибки из-за STL
От: Аноним  
Дата: 19.09.02 06:34
Оценка:
Да да я извиняюсь. Просто я сначала писал шаблонный класс — не сработало, я подумал, что дело в шаблонах (VC++ не совсем хорошо с ними дружит) и уже начал писать вопрос в конфу, а потом обнаружил, что и без шаблонов не прет, а operator<< просто забыл переписать нормально. Короче вот точный код:

#include <iostream>
#include <vector>
using namespace std;

class A
{
public:
    friend std::ostream& operator<< (std::ostream& os, const A& a);
    friend bool operator < (A&, A&);
private:
    int m_i;
};


bool operator < (A& a1, A& a2)
{
    return (a1.m_i < a2.m_i);
}


std::ostream& operator<< (std::ostream& os, const A& a)
{
    os << a.m_i;
    return os;
}

void main()
{
}


И я по прежнему утверждаю, что VC++ выдает "error C2248: 'm_i' : cannot access private member declared in class 'A'". Но если я убираю "using namespace std;", то все компилиться без ошибок.
Далее хочу сказать, что operator<< и operator< я выбрал совершенно случайно, без всякого умысла, чисто для теста. И если, например, объявить (даже определять не надо) operator+ то компилер выдаст "fatal error C1001: INTERNAL COMPILER ERROR".
Re[2]: Странные ошибки из-за STL
От: Stanley Kay  
Дата: 19.09.02 06:37
Оценка:
Здравствуйте Андрей Тарасевич, Вы писали:

АТ>"Работать замечательно" это никак не может. Этот код не должен компилироваться ни с 'using namespace std', ни без. Если он у тебя компилируется, то это действительно глюк компилятора.


Да да я извиняюсь. Просто я сначала писал шаблонный класс — не сработало, я подумал, что дело в шаблонах (VC++ не совсем хорошо с ними дружит) и уже начал писать вопрос в конфу, а потом обнаружил, что и без шаблонов не прет, а operator<< просто забыл переписать нормально. Короче вот точный код:

#include <iostream>
#include <vector>
using namespace std;

class A
{
public:
    friend std::ostream& operator<< (std::ostream& os, const A& a);
    friend bool operator < (A&, A&);
private:
    int m_i;
};


bool operator < (A& a1, A& a2)
{
    return (a1.m_i < a2.m_i);
}


std::ostream& operator<< (std::ostream& os, const A& a)
{
    os << a.m_i;
    return os;
}

void main()
{
}


И я по прежнему утверждаю, что VC++ выдает "error C2248: 'm_i' : cannot access private member declared in class 'A'". Но если я убираю "using namespace std;", то все компилиться без ошибок.
Далее хочу сказать, что operator<< и operator< я выбрал совершенно случайно, без всякого умысла, чисто для теста. И если, например, объявить (даже определять не надо) operator+ то компилер выдаст "fatal error C1001: INTERNAL COMPILER ERROR".
Re[2]: Странные ошибки из-за STL
От: Stanley Kay  
Дата: 19.09.02 06:41
Оценка:
Здравствуйте GYB, Вы писали:

GYB>В том виде как было у меня даже компилироваться не стало

Да это просто был старый код с template<> Вобщем там все template<> надо было убрать, я просто ошибся, когда писал вопрос сюда.

GYB>Но вот так вот работает всё

Нет так не работает (тот же вариант, что и был у меня). Не может он получить доступ к privateч-члену .
Re[3]: Это глюк компилятора
От: jazzer Россия Skype: enerjazzer
Дата: 19.09.02 06:57
Оценка:
Здравствуйте Stanley Kay, Вы писали:

SK>Здравствуйте Андрей Тарасевич, Вы писали:


АТ>>"Работать замечательно" это никак не может. Этот код не должен компилироваться ни с 'using namespace std', ни без. Если он у тебя компилируется, то это действительно глюк компилятора.


SK>Да да я извиняюсь. Просто я сначала писал шаблонный класс — не сработало, я подумал, что дело в шаблонах (VC++ не совсем хорошо с ними дружит) и уже начал писать вопрос в конфу, а потом обнаружил, что и без шаблонов не прет, а operator<< просто забыл переписать нормально. Короче вот точный код:

SK>

SK>#include <iostream>
SK>#include <vector>
SK>using namespace std;

SK>class A
SK>{
SK>public:
SK>    friend std::ostream& operator<< (std::ostream& os, const A& a);
SK>    friend bool operator < (A&, A&);
SK>private:
SK>    int m_i;
SK>};

SK>
SK>bool operator < (A& a1, A& a2)
SK>{
SK>    return (a1.m_i < a2.m_i);
SK>}

SK>
SK>std::ostream& operator<< (std::ostream& os, const A& a)
SK>{
SK>    os << a.m_i;
SK>    return os;
SK>}

SK>void main()
SK>{
SK>} 
SK>


SK>И я по прежнему утверждаю, что VC++ выдает "error C2248: 'm_i' : cannot access private member declared in class 'A'". Но если я убираю "using namespace std;", то все компилиться без ошибок.

SK>Далее хочу сказать, что operator<< и operator< я выбрал совершенно случайно, без всякого умысла, чисто для теста. И если, например, объявить (даже определять не надо) operator+ то компилер выдаст "fatal error C1001: INTERNAL COMPILER ERROR".

Только что я откомпилировал его компилятором CC: Sun WorkShop 6 update 1 C++ 5.2 2000/09/11
Единственное, на что он ругнулся:
Warning (Anachronism): main() must have a return type of int.

Как Вам правильно советовали, поставьте последний ServicePack. Или перейдите на VC7.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Странные ошибки из-за STL
От: Bell Россия  
Дата: 19.09.02 07:03
Оценка:
Здравствуйте Stanley Kay, Вы писали:

Приведенный тобой код прекрасно компилится VC6SP5 и если есть директива using namespace std и если ее нет.
Проверь — не осталось ли где перед объявлением класса А строки
template<class T>

ну или чего подобного.
Любите книгу — источник знаний (с) М.Горький
Re[4]: Это глюк компилятора
От: Bell Россия  
Дата: 19.09.02 07:05
Оценка:
Здравствуйте jazzer, Вы писали:


J>Только что я откомпилировал его компилятором CC: Sun WorkShop 6 update 1 C++ 5.2 2000/09/11

J>Единственное, на что он ругнулся:
J>Warning (Anachronism): main() must have a return type of int.

J>Как Вам правильно советовали, поставьте последний ServicePack. Или перейдите на VC7.

В VC6SP5 тоже компилится безо всяких проблем. Проблема похоже в чем-то другом.
Любите книгу — источник знаний (с) М.Горький
Re[4]: Странные ошибки из-за STL
От: Stanley Kay  
Дата: 19.09.02 07:19
Оценка:
Здравствуйте Bell, Вы писали:

B>Здравствуйте Stanley Kay, Вы писали:


B>Приведенный тобой код прекрасно компилится VC6SP5 и если есть директива using namespace std и если ее нет.

B>Проверь — не осталось ли где перед объявлением класса А строки
B>
B>template<class T>
B>

B>ну или чего подобного.

На сколько я знаю SP5 для VC у меня не стоит. Во всяком случае — как это можно проверить? — В About-e об этом не говорится, в реестре тоже вроде ничего не прописано. Все равно — спасибо — попробую.
Re[5]: Странные ошибки из-за STL
От: Bell Россия  
Дата: 19.09.02 07:31
Оценка:
Здравствуйте Stanley Kay, Вы писали:


SK>На сколько я знаю SP5 для VC у меня не стоит. Во всяком случае — как это можно проверить? — В About-e об этом не говорится, в реестре тоже вроде ничего не прописано. Все равно — спасибо — попробую.


Кстати, error C2248 — это единственная ошибка, или есть еще что-то?
Любите книгу — источник знаний (с) М.Горький
Re[6]: Странные ошибки из-за STL
От: Stanley Kay  
Дата: 19.09.02 09:34
Оценка:
Здравствуйте Bell, Вы писали:

B>Кстати, error C2248 — это единственная ошибка, или есть еще что-то?

Нет, больше никаких. Если конечно вы где-нить попробуете использовать эти операторы, то будет еще C2593 для всех таких операторов — 'operator X' is ambiguous
Re[5]: Странные ошибки из-за STL
От: Kaa Украина http://blog.meta.ua/users/kaa/
Дата: 19.09.02 14:46
Оценка:
Здравствуйте Stanley Kay, Вы писали:

SK>На сколько я знаю SP5 для VC у меня не стоит. Во всяком случае — как это можно проверить?


Если у тебя Вин2000, то проверить это можно попробовав открыть Build>Start Debug>Attach to process. Без сервис-пака (по-моему даже третьего, не то что пятого, хотя могу ошибаться) тамошний процесс-вьювер не отбражает никаких процессов. А под NT4 работает и без него.
Алексей Кирдин
Re[3]: Странные ошибки из-за STL
От: GYB  
Дата: 19.09.02 17:31
Оценка:
Здравствуйте Stanley Kay, Вы писали:

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


GYB>>В том виде как было у меня даже компилироваться не стало

SK>Да это просто был старый код с template<> Вобщем там все template<> надо было убрать, я просто ошибся, когда писал вопрос сюда.

GYB>>Но вот так вот работает всё

SK>Нет так не работает (тот же вариант, что и был у меня). Не может он получить доступ к privateч-члену .

Ok! Я кажется понял. У тебя стоит MSVC6 без сервиспаков. Я компилировал под MSVC7. Потом я компилировал под MSVC6 и получил такую-же ошибку. После установки MSVC6 SP3 всё стало компилироваться хорошо. Так что поставь сервиспак.
Re[3]: Странные ошибки из-за STL
От: Аноним  
Дата: 19.09.02 23:20
Оценка:
в VC7 Все замечательно компилится, и с шаблонами тоже
переходите на VC7
Re: Странные ошибки из-за STL
От: Fiend  
Дата: 20.09.02 14:04
Оценка:
У меня в вижуале тоже такое было. Можно еще попробовать сделать операторы встроенными, оп-моему будет работать.
Re[4]: Странные ошибки из-за STL
От: Stanley Kay  
Дата: 20.09.02 15:39
Оценка:
Здравствуйте GYB, Вы писали:

GYB>Здравствуйте Stanley Kay, Вы писали:


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


GYB>>>В том виде как было у меня даже компилироваться не стало

SK>>Да это просто был старый код с template<> Вобщем там все template<> надо было убрать, я просто ошибся, когда писал вопрос сюда.

GYB>>>Но вот так вот работает всё

SK>>Нет так не работает (тот же вариант, что и был у меня). Не может он получить доступ к privateч-члену .

GYB>Ok! Я кажется понял. У тебя стоит MSVC6 без сервиспаков. Я компилировал под MSVC7. Потом я компилировал под MSVC6 и получил такую-же ошибку. После установки MSVC6 SP3 всё стало компилироваться хорошо. Так что поставь сервиспак.

Да, да поставил сервиспак 5 — и заработало. Спасибо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.