У меня есть класс под названием Circle, который я инкапсулировал в пространство имен.
namespace my_name_space {
class Circle;
}
class my_name_space::Circle {
private:
double radius;
public:
friend std::ostream& operator << (std::ostream &os, const Circle &c);
};
Вот функция в файле реализации:
std::ostream& operator << (std::ostream &os, const Circle &c)
{
os << "Radius: " << c.radius;
return os;
}
Перед инкапсуляцией класса в пространство имен все работало нормально. Теперь функция друга больше не может получить доступ к частным элементам данных. Я не понимаю в чем дело.





Когда вы объявляете operator << как друг для Circle, он становится членом самого внутреннего включающего пространства имен Circle. Это означает, что когда вы помещаете Circle в пространство имен my_name_space, operator << также становится членом пространства имен my_name_space. Определение operator<< не совпадает с этим, оно определяет operator<< в глобальном масштабе.
A name first declared in a friend declaration within class or class template X becomes a member of the innermost enclosing namespace of X
Вы можете переместить определение operator<< в пространство имен my_name_space:
namespace my_name_space {
std::ostream& operator << (std::ostream &os, const Circle &c) {
...
}
}
Или, если вы все еще хотите сохранить operator<< в глобальном масштабе:
// delcaration
std::ostream& operator << (std::ostream &os, const my_name_space::Circle &c);
class my_name_space::Circle {
...
friend std::ostream& ::operator << (std::ostream &os, const Circle &c);
// ~~
};
// definition
std::ostream& operator << (std::ostream &os, const my_name_space::Circle &c) {
...
}
@MutatingAlgorithm Да. using namespace my_name_space; не будет делать деклараций после того, как станет членом my_name_space.
Объявление using объясняет, почему код OP, скомпилированный с const Circle &c, неквалифицирован. Для меня это было загадкой.
Ваше первое предложение дает предупреждение компилятору, а второе - нет.
@OrenIshShalom Я использую clang, и он не пропускает никаких предупреждений. Я не уверен, какой из них правильный; в любом случае я изменил стиль, который не вызовет сомнений.
что, если у меня есть объявление использования в верхней части файла реализации, так как
using my_namespaceдолжен лиoperatorвсе еще быть квалифицированным?