Функция-член класса X без параметров с именем формы
conversion-function-id: operator conversion-type-id
conversion-type-id: type-specifier-seq conversion-declaratoropt
conversion-declarator: ptr-operator conversion-declaratoropt
указывает преобразование из X в тип, указанный в conversion-type-id. Такие функции называются conversion functions. A decl-specifierв decl-specifier-seq функции преобразования (если есть) не должно быть ни a, defining-type-specifierни static. Тип функции преобразования ([dcl.fct]) - «функция, не возвращающая никаких параметров conversion-type-id». Функция преобразования никогда не используется для преобразования объекта (возможно, квалифицированного cv) в (возможно, квалифицированный cv) объект того же типа (или ссылку на него) в базовый класс (возможно, квалифицированный cv) этого типа (или ссылка на него) или на (возможно cv-квалифицированный) void.117 [ Example:
struct X {
operator int();
operator auto() -> short; // error: trailing return type
};
void f(X a) {
int i = int(a);
i = (int)a;
i = a;
}
Во всех трех случаях присвоенное значение будет преобразовано в X::operator int(). ] — end example
Функция преобразования может быть explicit, и в этом случае она рассматривается только как определяемое пользователем преобразование для direct-initialization. В противном случае пользовательские преобразования не ограничиваются использованием в назначениях и инициализациях. [ Example:
class Y { }; struct Z { explicit operator Y() const; }; void h(Z z) { Y y1(z); // OK: direct-initialization Y y2 = z; // ill-formed: copy-initialization Y y3 = (Y)z; // OK: cast notation } void g(X a, X b) { int i = (a) ? 1+a : 0; int j = (a&&b) ? a+b : i; if (a) { } }
— end example ]
Не conversion-type-id должен представлять тип функции или тип массива. In conversion-type-id a conversion-function-id - это самая длинная последовательность токенов, которая могла бы образовать conversion-type-id. [ Note: Это предотвращает двусмысленность между оператором-декларатором * и его эквивалентами-выражениями. [ Example:
&ac.operator int*i; // syntax error: // parsed as: &(ac.operator int *)i // not as: &(ac.operator int)*i
Это * декларатор указателя, а не оператор умножения. ] Это правило также предотвращает двусмысленность атрибутов. [ — end example Example:
operator int [[noreturn]] (); // error: noreturn attribute applied to a type
— end example ] ] — end note
В шаблоне функции преобразования не должно быть файла deduced return type. [ Example:
struct S { operator auto() const { return 10; } // OK template<class T> operator auto() const { return 1.2; } // error: conversion function template };
— end example ]
Эти преобразования считаются стандартными в целях разрешения перегрузки ([over.best.ics], [over.ics.ref]) и, следовательно, инициализации ([dcl.init]) и explicit casts. Преобразование в void не вызывает никакой функции преобразования ([expr.static.cast]). Даже если они никогда не вызываются напрямую для выполнения преобразования, такие функции преобразования могут быть объявлены и потенциально могут быть достигнуты посредством вызова функции виртуального преобразования в базовом классе.