Можно ли объявить функцию преобразования, возвращающую ссылку на массив без 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() ;
Другие вопросы по тегам