Southmountain Ответов: 1

Простой вопрос об использовании оператора namespace в VC++


Я протестировал демо-версию из эта ссылка чтобы проверить оператор using namespace. Я получил это сообщение об ошибке:

Severity	Code	Description	Project	File	Line	Suppression State
Error	C2664	'void One::funct1(char)': cannot convert argument 1 from 'const char [15]' to 'char *'	namespace04	c:\demo\namespace04\namespace04\main.cpp	35	


похоже
void funct1(char *str)
не признанный.

вот полный код для вашего удобства:
//explicit access, namespace within a class
#include <iostream>
using namespace std;

class One
{
	public:
		void funct1(char chs)
		{
			cout << "character = " << chs << endl;
		}
};

class Two :public One
{
	public:
		//The using directive is not allowed in class using namespace One;
		void funct1(char *str)
		{
			cout << "String = " << str << endl;
		}

		// using declaration is OK in class
		using One::funct1;  // overload Two::funct1()
};


int main(void)
{
	Two Sample;
	// calling One::funct1()
	Sample.funct1('P');

	// calling Two::funct1()
	Sample.funct1("This is string"); <==== error line is this statement

	return 0;

}


Что я уже пробовал:

пробовал, но не могу найти теоретической причины этой ошибки...

1 Ответов

Рейтинг:
12

Greg Utas

Two происходит от One. Оба объявляют функцию funct1. Декларация в Two скрывает декларация в One, так что он больше не доступен.

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

EDIT2: Видеть этот[^]. Твой using оператор предназначен для члена класса, а не для пространства имен, и соответствующее объяснение таково

Using-declaration вводит член базового класса в определение производного класса, например, чтобы предоставить защищенный член base в качестве открытого члена производного. В этом случае спецификатор вложенного имени должен называть базовый класс определяемого класса. Если имя является именем перегруженной функции-члена базового класса, то вводятся все функции-члены базового класса с этим именем. Если производный класс уже имеет член с тем же именем, списком параметров и квалификациями, то член производного класса скрывает или переопределяет (не конфликтует) член, введенный из базового класса.
Я не знаю, как истолковать последнее предложение, скрывает или переопределяет (не конфликтует с). Ваша функция не является надлежащим переопределением, потому что эта функция не является таковой virtual Таким образом, предложение, по-видимому, подразумевает, что оно скрывает, но не противоречит имени базового класса. Для меня это не имеет никакого смысла.


Southmountain

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

Greg Utas

Нет, это не нормально, хотя вполне возможно, что оператор using позволяет ему успешно компилироваться (я использую VS2017). Соответствует ли это спецификации - другой вопрос. Это кажется полезным, но приведенная выше цитата предполагает, что он не может быть портативным. Более того, почему вы хотите это сделать? Просто используй другое имя.

Southmountain

большое вам спасибо за ваше время! Теперь я понимаю ваш ответ.

что вы сделали для вашего EDIT1, чтобы он был скомпилирован? Мне любопытно это знать...

Greg Utas

Я только удалил <==== "комментарий" в строке, где вы получили ошибку.

Greg Utas

Вы должны были прокомментировать "использование пространства имен One", потому что One-это класс, а не пространство имен.

Southmountain

Большое спасибо! Я тестирую эту демонстрацию, чтобы получить больше понимания концепции пространства имен. во всех других случаях использования пространства имен я хорошо играл, пока не столкнулся с этим случаем.

Greg Utas

Всегда пожалуйста!