Можно ли объявить функцию преобразования, возвращающую ссылку на массив без typedef?
Вот функция преобразования, возвращающая ссылку на массив:
struct S {
typedef int int_array_20[20];
operator int_array_20& ();
};
Можно ли сделать то же самое без typedef
? Что я пробовал:
struct S {
operator int (&()) [10];
};
но лязг жалуется
error: C++ requires a type specifier for all declarations
operator int (&()) [10];
~ ^
error: conversion function cannot have any parameters
operator int (&()) [10];
^
error: must use a typedef to declare a conversion to 'int [10]'
error: conversion function cannot convert to an array type
Имеет:
должен использовать typedef, чтобы объявить преобразование в 'int [10]'
имею в виду typedef
это обязательно?
РЕДАКТИРОВАТЬ
Если typedef
необходимо, невозможно создать шаблон функции преобразования, как показано ниже, потому что не удалось определить typedef
шаблон, это правильно?
struct S {
template<typename T, int N>
operator T(&())[N];
};
1 ответ
Да, это действительно необходимо, мы можем увидеть это, перейдя в раздел cppreference, определяемый пользователем, который говорит:
Операторы функций и массивов [] или () недопустимы в деклараторе (поэтому преобразование в типы, такие как указатель на массив, требует typedef: см. Ниже). Независимо от typedef, ID-типа-преобразования не может представлять массив или тип функции.
Мы можем найти это в проекте стандарта C++ 12.3.2
Функции преобразования, которые говорят:
Идентификатор типа преобразования не должен представлять тип функции или тип массива. Идентификатор типа преобразования в идентификаторе функции преобразования является самой длинной из возможных последовательностей объявлений-преобразователей. [Примечание: это предотвращает неоднозначность между оператором объявления * и его аналогами выражений. [ Пример:
&ac.operator int*i; // syntax error: // parsed as: &(ac.operator int *)i // not as: &(ac.operator int)*i
* Является декларатором указателя, а не оператором умножения. - конец примера] - конец заметки]
и грамматика для ID-типа преобразования выглядит следующим образом:
conversion-type-id: type-specifier-seq conversion-declaratoropt conversion-declarator: ptr-operator conversion-declaratoropt
который более ограничен, чем декларатор, грамматика которого выглядит следующим образом:
declarator: ptr-declarator noptr-declarator parameters-and-qualifiers trailing-return-type ptr-declarator: noptr-declarator ptr-operator ptr-declarator noptr-declarator: declarator-id attribute-specifier-seqopt noptr-declarator parameters-and-qualifiers noptr-declarator [ constant-expressionopt] attribute-specifier-seqopt ( ptr-declarator )
Одна из альтернатив, о которой упоминал Крис, заключалась в использовании класса идентичности:
template <typename T>
struct identity
{
typedef T type;
};
вы бы использовали его следующим образом:
operator typename identity<int(&)[10]>::type() ;