Использование полного имени в параметре функции - PullRequest
2 голосов
/ 11 декабря 2010

В соответствии со стандартом C ++ имя параметра функции анализируется с помощью идентификатор объявления , а идентификатор объявления также может быть полным именем. Это означает, что следующий код является абсолютно допустимым (если я правильно понял соответствующие разделы стандарта):

template<class T>
struct Sample
{
    int fun(int T::count); //T::count is qualified variable name
};

Мой вопрос в основном таков: зачем кому-то писать такой код? В каких ситуациях использование квалифицированного имени (в списке параметров функции) может быть выгодным?


EDIT:

Кажется, я неправильно понял разделы. Вместо приведенного выше кода мы, вероятно, можем написать следующий код (согласно стандарту C ++):

template<class T>
struct sample
{
  void fun(int arr[T::count]);
};

gcc-4.3.4 компилирует это отлично. Но тогда я не совсем удовлетворен, потому что T :: count больше не является параметром (я думаю).

Ответы [ 3 ]

2 голосов
/ 11 декабря 2010

Это недействительно.Синтаксис допускает произвольные объявления, но 8.3.5p8 говорит:

Идентификатор может быть необязательно предоставлен в качестве имени параметра;если присутствует в определении функции (8.4), он называет параметр (иногда называемый «формальным аргументом»)

Edit Другая цитата, которая синтаксически ограничивает деклараторы (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.

1 голос
/ 11 декабря 2010

Насколько я понимаю, ваш код плохо сформирован, потому что

$ 8.3 / 1: Когда идентификатор объявления определен, объявление должно ссылаться на ранее объявленного члена классаили пространство имен, к которому относится квалификатор , и член не должен быть введен объявлением использования в области видимости класса или пространства имен, назначенных спецификатором nested-name идентификатора объявления.[Примечание: если квалификатор является оператором разрешения global :: scope, идентификатор объявления ссылается на имя, объявленное в глобальной области пространства имен.]

PS: Я не уверен на 100%.Пожалуйста, поправьте меня, если я ошибаюсь.:)


В каких ситуациях использование квалифицированного имени (в списке параметров функции) может быть выгодным?

Чтение элементов 31 и 32 из исключительныхC ++ Херб Саттер.Оба предмета касаются поиска Кенига и принципа интерфейса.

0 голосов
/ 11 декабря 2010

Кажется, я неправильно понял разделы. Вместо этого кода мы, вероятно, можем написать следующий код (согласно стандарту C ++):

template<class T>
struct sample
{
  void fun(int arr[T::count]);
};

gcc-4.3.4 компилирует это отлично. Но тогда я не совсем доволен, потому что T::count больше не является параметром (наверное).

...