Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Область видимости операторов / 9 сообщений из 9, страница 1 из 1
07.06.2013, 13:56
    #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
07.06.2013, 14:25
    #38290294
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Область видимости операторов
Compositum,

Есть еще один случай, когда функции можно вызывать без неймспейса - если функция объявлена в одном из неймспейсов передаваемых в нее аргументов.
Это правило называется argument dependent lookup
Именно с этим случаем вы столкнулись (операторы - тоже функции)
...
Рейтинг: 0 / 0
07.06.2013, 14:27
    #38290297
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Область видимости операторов
Собственно, ADL и был введен в язык для операторов.
...
Рейтинг: 0 / 0
07.06.2013, 14:52
    #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
07.06.2013, 14:56
    #38290383
Compositum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Область видимости операторов
ой, извиняюсь - второй код не компилируется. :) Я внёс изменения в копию файла, а откомпилировал оригинал. :)
...
Рейтинг: 0 / 0
07.06.2013, 14:57
    #38290385
Compositum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Область видимости операторов
Anatoly MoskovskyCompositum,

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

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

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


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