powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Область видимости операторов
9 сообщений из 9, страница 1 из 1
Область видимости операторов
    #38290227
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток.

При использовании функции, следует
- либо указывать её полное имя, включая пространство имён,
- либо имя, с префиксом, назначенным пространству имён (чтобы не набирать каждый раз полное),
- либо только имя, если пространство имён подключено через using namespace .

Я ожидал, что это правило распространяется и на операторы, однако создаётся впечатление, что их область видимости глобальна. Т.е. если я вызываю оператор как функцию, то независимо от того, указываю ли я пространство имён, или же нет - всё компилируется и выполняется, хотя я ожидаю ошибку компиляции в строке, в которой имя оператора указано без namespace.

Далее простой код с комментариями:
Код: plaintext
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.
65.
66.
67.
68.
69.
/*
sample.cpp
*/
//-------------------------------------------------------
#include <iostream>
#include <exception>
using namespace std;
namespace My_some_namespace{
//-------------------------------------------------------
	class My_class
	// My some class
	{
	private:
		int x;
	public:
		int value() const { return x; }
		void value(int val) { x = val; }
		My_class(int n): x(n) {}
	};
//-------------------------------------------------------
	My_class operator ++ (My_class& n)
	// prefix increment
	{
		cout << " Hello from prefix increment! ";
		n.value(n.value() + 1);
		return n;
	}
//-------------------------------------------------------
	My_class operator ++ (My_class& n, int)
	// postfix increment
	{
		cout << " Hello from postfix increment! ";
		My_class m = n;
		n.value(n.value() + 1);
		return m;
	}
	ostream& operator << (ostream& os, const My_class& n)
	// output to stream
	{
		os << n.value();
		return os;
	}
}
//=======================================================
int main()
try{
	namespace AB = My_some_namespace; // Назначил псевдоним пространству.
	AB::My_class x(100);
	cout << "x = " << x << endl;
	cout << "++x = " << ++x << endl;
	cout << "AB::operator++(x);" << endl;
	AB::operator++(x); // Указываю пространство имён.
	cout << "x = " << x << endl;
	cout << "operator++(x);" << endl;
	// В следующей строке ожидаю получить ошибку компиляции,
	// т.к. не указал пространство имён, и НЕ подключаю его
	// с помощью 'using namespace'. Однако ошибки не происходит...
	operator++(x); // НЕ указываю пространство имён.
	cout << "x = " << x << endl;
}
catch(exception& e){
	cerr << e.what() << endl;
	return 1;
}
catch(...){
	cerr << "Unknown excetion." << endl;
	return 2;
}
//=======================================================


Результат работы кода:
Консольный выводx = 100
Hello from prefix increment! ++x = 101
AB::operator++(x);
Hello from prefix increment! x = 102
operator++(x);
Hello from prefix increment! x = 103

Вопрос: Почему я не получаю ошибки компиляции при вызове оператора в стиле, подобном вызову функции, если не указываю её namespace?

Спасибо.
...
Рейтинг: 0 / 0
Область видимости операторов
    #38290294
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Compositum,

Есть еще один случай, когда функции можно вызывать без неймспейса - если функция объявлена в одном из неймспейсов передаваемых в нее аргументов.
Это правило называется argument dependent lookup
Именно с этим случаем вы столкнулись (операторы - тоже функции)
...
Рейтинг: 0 / 0
Область видимости операторов
    #38290297
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно, ADL и был введен в язык для операторов.
...
Рейтинг: 0 / 0
Область видимости операторов
    #38290371
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

Благодарю за ответ! Немного изменил код: создал дополнительный namespace и определения всех операторов переместил в него. Причём, обратите внимание, типы возвращаемых значений и типы аргументов в этих операторах не содержат пространств имён(!!!):
Код: plaintext
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.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
/*
sample.cpp
*/
//-------------------------------------------------------
#include <iostream>
#include <exception>
using namespace std;
//*******************************************************
namespace My_some_namespace{
//-------------------------------------------------------
	class My_class
	// My some class
	{
	private:
		int x;
	public:
		int value() const { return x; }
		void value(int val) { x = val; }
		My_class(int n): x(n) {}
	};
} // end of My_some_namespace

//*******************************************************
namespace Some_other_namespace{
	//-------------------------------------------------------
	My_class operator ++ (My_class& n)
	// prefix increment
	{
		cout << " Hello from prefix increment! ";
		n.value(n.value() + 1);
		return n;
	}
//-------------------------------------------------------
	My_class operator ++ (My_class& n, int)
	// postfix increment
	{
		cout << " Hello from postfix increment! ";
		My_class m = n;
		n.value(n.value() + 1);
		return m;
	}
//-------------------------------------------------------
	ostream& operator << (ostream& os, const My_class& n)
	// output to stream
	{
		os << n.value();
		return os;
	}
} // end of Some_other_namespace

//=======================================================
int main()
// entry point
try{
	namespace AB = My_some_namespace; // Назначил псевдоним пространству.
	AB::My_class x(100);
	cout << "x = " << x << endl;
	cout << "++x = " << ++x << endl;
	cout << "AB::operator++(x);" << endl;
	AB::operator++(x); // Указываю пространство имён.
	cout << "x = " << x << endl;
	cout << "operator++(x);" << endl;
	// В следующей строке ожидаю получить ошибку компиляции,
	// т.к. не указал пространство имён, и НЕ подключаю его
	// с помощью 'using namespace'. Однако ошибки не происходит...
	operator++(x); // НЕ указываю пространство имён.
	cout << "x = " << x << endl;
}
catch(exception& e){
	cerr << e.what() << endl;
	return 1;
}
catch(...){
	cerr << "Unknown excetion." << endl;
	return 2;
}
//=======================================================


Код по прежнему компилируется и выполняется. Т.е. компилятор каким-то образом "знает", в каком пространстве имён ему искать "My_class"... Почему я не получаю ошибок компиляции не смотря на то, что не указываю полные имена типов в возвращаемых значениях и в аргументах операторов?

Спасибо.
...
Рейтинг: 0 / 0
Область видимости операторов
    #38290383
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ой, извиняюсь - второй код не компилируется. :) Я внёс изменения в копию файла, а откомпилировал оригинал. :)
...
Рейтинг: 0 / 0
Область видимости операторов
    #38290385
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyCompositum,

Есть еще один случай, когда функции можно вызывать без неймспейса - если функция объявлена в одном из неймспейсов передаваемых в нее аргументов.
Это правило называется argument dependent lookup
Именно с этим случаем вы столкнулись (операторы - тоже функции)
Спасибо большое, буду знать! :)
...
Рейтинг: 0 / 0
Область видимости операторов
    #38290387
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Compositum,

Не верю. Простите :)
...
Рейтинг: 0 / 0
Область видимости операторов
    #38290390
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyCompositum,

Не верю. Простите :)
Это относилось к "прежнему компилируется"
...
Рейтинг: 0 / 0
Область видимости операторов
    #38290395
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyЭто относилось к "прежнему компилируется"
да, я понял :)
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Область видимости операторов
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]