Использование полного имени в параметре функции
В соответствии со стандартом C++ имя параметра функции анализируется по идентификатору декларатора, а идентификатор декларатора также может быть квалифицированным именем. Это означает, что следующий код является абсолютно допустимым (если я правильно понял соответствующие разделы стандарта):
template<class T>
struct Sample
{
int fun(int T::count); //T::count is qualified variable name
};
Мой вопрос в основном: зачем кому-то писать такой код? В каких ситуациях использование квалифицированного имени (в списке параметров функции) может быть выгодным?
РЕДАКТИРОВАТЬ:
Кажется, я неправильно понял разделы. Вместо приведенного выше кода мы, вероятно, можем написать следующий код (согласно стандарту C++):
template<class T>
struct sample
{
void fun(int arr[T::count]);
};
gcc-4.3.4 компилирует это отлично. Но тогда я не совсем удовлетворен, потому что T::count больше не является параметром (я полагаю).
3 ответа
Это неверно. Синтаксис допускает произвольные объявления, но 8.3.5p8 говорит
При желании идентификатор может быть предоставлен как имя параметра; если присутствует в определении функции (8.4), он называет параметр (иногда называемый "формальным аргументом")
Редактировать еще одну цитату, которая синтаксически ограничивает деклараторы (8.3p1, [dcl.meaning]):
Каждый декларатор содержит ровно один идентификатор декларатора; он называет идентификатор, который объявлен. Выражение id объявления-идентификатора должно быть простым идентификатором, за исключением объявления некоторых специальных функций (12.3, 12.4, 13.5) и объявления специализаций шаблона или частичных специализаций (14.7). Идентификатор объявления не должен уточняться, за исключением определения функции-члена (9.3) или статического члена данных (9.4) или вложенного класса (9.7) вне его класса, определения или явного создания экземпляра функции, переменной или члена класса пространства имен за пределами его пространства имен, или определения ранее объявленной явной специализации за пределами его пространства имен, или объявления функции-друга, которая является членом другого класса или пространства имен (11.4).
Таким образом, в объявлении параметра нельзя использовать квалифицированные имена.
Редактировать: в редактируемой форме тип параметра функции уменьшается до int*
, даже до того, как проводится проверка T::count
на самом деле существует и является целочисленной константой. Если вам нужен пример, в котором квалифицированное имя в такой подписи могло бы что-то значить, подумайте
template<class T>
struct sample
{
void fun(int S=T::count);
};
когда fun
вызывается без параметра, компилятор должен определить аргумент по умолчанию, который затем завершается ошибкой, если T
не имеет count
член, или который не может быть преобразован в int
,
Насколько я понимаю, твой код плохо сформирован, потому что
$8.3/1: Когда идентификатор объявления определен, объявление должно ссылаться на ранее объявленного члена класса или пространства имен, на которое ссылается классификатор, и этот член не должен быть введен объявлением использования в области действия класс или пространство имен, назначенное спецификатором nested-name идентификатора объявления. [Примечание: если квалификатор является оператором разрешения global::scope, то идентификатор объявления ссылается на имя, объявленное в глобальной области пространства имен. ]
PS: я не уверен на 100%. Пожалуйста, поправьте меня, если я ошибаюсь.:)
В каких ситуациях использование квалифицированного имени (в списке параметров функции) может быть выгодным?
Прочитайте статьи 31 и 32 из "Исключительного C++" Херба Саттера. Оба элемента имеют дело с поиском Кенига и принципом интерфейса.
Кажется, я неправильно понял разделы. Вместо этого кода мы, вероятно, можем написать следующий код (согласно стандарту C++):
template<class T>
struct sample
{
void fun(int arr[T::count]);
};
gcc-4.3.4 компилирует это отлично. Но тогда я не совсем доволен, потому что T::count
больше не является параметром (наверное).