#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").
А>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").
А>Не подскажите причину такого поведения?
В том виде как было у меня даже компилироваться не стало
А>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".
Здравствуйте Андрей Тарасевич, Вы писали:
АТ>"Работать замечательно" это никак не может. Этот код не должен компилироваться ни с '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".
Здравствуйте GYB, Вы писали:
GYB>В том виде как было у меня даже компилироваться не стало
Да это просто был старый код с template<> Вобщем там все template<> надо было убрать, я просто ошибся, когда писал вопрос сюда.
GYB>Но вот так вот работает всё
Нет так не работает (тот же вариант, что и был у меня). Не может он получить доступ к privateч-члену .
Здравствуйте Stanley Kay, Вы писали:
SK>Здравствуйте Андрей Тарасевич, Вы писали:
АТ>>"Работать замечательно" это никак не может. Этот код не должен компилироваться ни с 'using namespace std', ни без. Если он у тебя компилируется, то это действительно глюк компилятора.
SK>Да да я извиняюсь. Просто я сначала писал шаблонный класс — не сработало, я подумал, что дело в шаблонах (VC++ не совсем хорошо с ними дружит) и уже начал писать вопрос в конфу, а потом обнаружил, что и без шаблонов не прет, а operator<< просто забыл переписать нормально. Короче вот точный код: 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.
Приведенный тобой код прекрасно компилится VC6SP5 и если есть директива using namespace std и если ее нет.
Проверь — не осталось ли где перед объявлением класса А строки
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 тоже компилится безо всяких проблем. Проблема похоже в чем-то другом.
Здравствуйте Bell, Вы писали:
B>Здравствуйте Stanley Kay, Вы писали:
B>Приведенный тобой код прекрасно компилится VC6SP5 и если есть директива using namespace std и если ее нет. B>Проверь — не осталось ли где перед объявлением класса А строки B>
B>template<class T>
B>
B>ну или чего подобного.
На сколько я знаю SP5 для VC у меня не стоит. Во всяком случае — как это можно проверить? — В About-e об этом не говорится, в реестре тоже вроде ничего не прописано. Все равно — спасибо — попробую.
SK>На сколько я знаю SP5 для VC у меня не стоит. Во всяком случае — как это можно проверить? — В About-e об этом не говорится, в реестре тоже вроде ничего не прописано. Все равно — спасибо — попробую.
Кстати, error C2248 — это единственная ошибка, или есть еще что-то?
Здравствуйте Bell, Вы писали:
B>Кстати, error C2248 — это единственная ошибка, или есть еще что-то?
Нет, больше никаких. Если конечно вы где-нить попробуете использовать эти операторы, то будет еще C2593 для всех таких операторов — 'operator X' is ambiguous
Здравствуйте Stanley Kay, Вы писали:
SK>На сколько я знаю SP5 для VC у меня не стоит. Во всяком случае — как это можно проверить?
Если у тебя Вин2000, то проверить это можно попробовав открыть Build>Start Debug>Attach to process. Без сервис-пака (по-моему даже третьего, не то что пятого, хотя могу ошибаться) тамошний процесс-вьювер не отбражает никаких процессов. А под NT4 работает и без него.
Здравствуйте 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
Здравствуйте GYB, Вы писали:
GYB>Здравствуйте Stanley Kay, Вы писали:
SK>>Здравствуйте GYB, Вы писали:
GYB>>>В том виде как было у меня даже компилироваться не стало SK>>Да это просто был старый код с template<> Вобщем там все template<> надо было убрать, я просто ошибся, когда писал вопрос сюда.
GYB>>>Но вот так вот работает всё SK>>Нет так не работает (тот же вариант, что и был у меня). Не может он получить доступ к privateч-члену .
GYB>Ok! Я кажется понял. У тебя стоит MSVC6 без сервиспаков. Я компилировал под MSVC7. Потом я компилировал под MSVC6 и получил такую-же ошибку. После установки MSVC6 SP3 всё стало компилироваться хорошо. Так что поставь сервиспак.
Да, да поставил сервиспак 5 — и заработало. Спасибо.