2012-02-05 3 views
5

Мне было интересно, если кто-нибудь знает, какие ограничения находятся на операторе преобразования/типа?Существуют ли какие-либо ограничения на типы операторов-операторов?

Так, например, я могу иметь следующие операторы переопределения:

class Test { 
    operator int() { return 0; }; 
    operator int*() { return nullptr; }; 
} 

Для регулярной функции, я мог также иметь указатель на тип массива. Например.

int (*MyFunc())[4] { return nullptr; }; 

Однако, я не знаю, как сделать то же самое для оператора преобразования (или, если это даже законно сделать это). Я пробовал несколько разных вариантов и VS2010, и никто не работает. (Такие, как :)

operator int (*())[4] { return nullptr; }; 
operator int(*)[4]() { return nullptr; }; 

Я не уверен, если это ограничение в VS2010 или, если есть общий лимит на типах, которые могут быть использованы в операторе преобразования. Я пробовал искать стандартный онлайн без везения. Кто-нибудь знает? Прежде чем кто-нибудь спросит: «Почему бы вам это сделать?», Это для автоматически сгенерированного кода. Хотя я не ожидаю получения указателя на ввод массива, я хотел бы иметь возможность создавать код, если он является законным в C++.

ответ

3

Да, существует ограничения. Ограничение, которое вы попали в массивы, связано с грамматикой языка. Спецификация грамматики для оператора преобразования (и родственников) выглядит следующим образом:

 
§12.3.2 
conversion-function-id: 
    operator conversion-type-id 
conversion-type-id: 
    type-specifier-seq conversion-declarator[opt] 
conversion-declarator: 
    ptr-operator conversion-declarator[opt] 

§7.1.6 
type-specifier: 
    trailing-type-specifier 
    class-specifier 
    enum-specifier 
trailing-type-specifier: 
    simple-type-specifier 
    elaborated-type-specifier 
    typename-specifier 
    cv-qualifier 
type-specifier-seq: 
    type-specifier attribute-specifier-seq[opt] 
    type-specifier type-specifier-seq 
trailing-type-specifier-seq: 
    trailing-type-specifier attribute-specifier-seq[opt] 
    trailing-type-specifier trailing-type-specifier-seq 

Я оставляю это в качестве упражнения для читателя, чтобы посмотреть на всех, но вы не можете определить массив в качестве типа непосредственно. (. Оно указывается только в деклараций) К счастью, хотя, имя ЬурейеЕ допускается (через TYPENAME спецификатор), а также потому, ЬурейеЕ является своего рода декларацией, там работают массивы:

struct Test { 
    typedef int operator_type[4]; 

    operator operator_type*() { return nullptr; }; 
}; 

Короче говоря, используйте typedef, и вы можете использовать любой тип, который вам нужен.

+0

Спасибо. Это точно ответил на мой вопрос. –

+0

Комментарий Downvote? – GManNickG

6

Вы должны в основном использовать typedef в жестких конструкциях, а также вы получили синтаксис неправильный,

operator Type() {}

Я собираюсь использовать typedef сек, хотя

typedef int (*foo())[4]; 
typedef int(*bar)[4]; 

используя ЬурейеЕ

operator foo() { return nullptr; } // здесь вы пытаетесь преобразовать nullptr до «function», который возвращает указатель на массив из 4 int, что, очевидно, неверно.

operator bar() { return nullptr; } // Ваше второе преобразование действует, хотя, так как вы преобразование nullptr в указателе на массив 4 int сек

+0

Да, я надеялся избежать использования typedef, но я думаю, что выбора нет. –

Смежные вопросы