C++
语言 | Language

user-defined conversion

用户定义转换

使隐式转换或显式转换从类类型另一种类型。

句法

转换函数被声明为非静态成员函数或成员功能模板没有显式的返回类型,并使用表单的名称:

operator conversion-type-id(1)
explicit operator conversion-type-id(2)(since C++11)

1%29声明一个用户定义的转换函数,它参与所有隐式和显式转换

2%29定义一个用户定义的转换函数,该转换函数参与直接初始化和显式转换只有。

转换类型id是类型id除了该函数和数组运算符[]()在其声明器%28中不允许将其转换为类型,如指针到数组,需要类型别名/类型胡枝子或标识模板:请参见下面的%29。不管类型是什么,转换类型id都不能表示数组或函数类型。

虽然在用户定义的转换函数的声明中不允许返回类型,但声明语法可能存在,并且可能包括类型说明符或关键字静态以外的任何说明符,特别是除了explicit,说明符内联,,,虚拟,,,司法官,和朋友也允许%28注意friend需要有限定名称:friend A::operator B(29%。

当在类X中声明该成员函数时,它执行从X到转换类型id的转换:

二次

struct X { //implicit conversion operator int() const { return 7; } // explicit conversion explicit operator int*() const { return nullptr; } // Error: array operator not allowed in conversion-type-id // operator int(*)[3]() const { return nullptr; } using arr_t = int[3]; operator arr_t*() const { return nullptr; } // OK if done through typedef // operator arr_t () const; // Error: conversion to array not allowed in any case }; int main() { X x; int n = static_cast<int>(x // OK: sets n to 7 int m = x; // OK: sets m to 7 int* p = static_cast<int*>(x // OK: sets p to null // int* q = x; // Error: no implicit conversion int (*pa)[3] = x; // OK }

二次

解释

第二阶段调用用户定义的转换函数。隐式转换,由0或1组成。转换构造函数或零或一个用户定义的转换函数。

如果可以同时使用转换函数和转换构造函数来执行用户定义的转换,则转换函数和构造函数都由过载分辨率在复制初始化和参考初始化上下文,但只有构造函数在直接初始化背景。

二次

struct To { To() = default; To(const struct From&) {} // converting constructor }; struct From { operator To() const {return To(} // conversion function }; int main() { From f; To t1(f // direct-initialization: calls the constructor // (note, if converting constructor is not available, implicit copy constructor // will be selected, and conversion function will be called to prepare its argument) To t2 = f; // copy-initialization: ambiguous // (note, if conversion function is from a non-const type, e.g. // From::operator To(, it will be selected instead of the ctor in this case) To t3 = static_cast<To>(f // direct-initialization: calls the constructor const To& r = f; // reference-initialization: ambiguous }

二次

将函数转换为它自己的%28可能是cv限定%29类%28或对它的引用%29、它自己的类%28的基或对它的%29的引用以及类型。void可以定义,但不能作为转换序列的一部分执行,除非在某些情况下虚拟派遣:

二次

struct D; struct B { virtual operator D() = 0; }; struct D : B { operator D() override { return D( } }; int main() { D obj; D obj2 = obj; // does not call D::operator D() B& br = obj; D obj3 = br; // calls D::operator D() through virtual dispatch }

二次

还可以使用成员函数调用语法调用它:

二次

struct B {}; struct X : B { operator B&() { return *this; }; }; int main() { X x; B& b1 = x; // does not call X::operatorB&() B& b2 = static_cast<B&>(x // does not call X::operatorB& B& b3 = x.operator B&( // calls X::operator& }

二次

当对转换函数进行显式调用时,类型id是贪婪的:如果有任何%29,则它是有效的id%28包含属性的最长的令牌序列:

二次

& x.operator int * a; // parsed as & (x.operator int*) a // not as & (x.operator int) * a

二次

The placeholder auto can be used in conversion-type-id, indicating a deduced return type: struct X { operator int( // OK operator auto() -> short; // error: trailing return type not part of syntax operator auto() const { return 10; } // OK: deduced return type }; Note: a conversion function template is not allowed to have a deduced return type.(since C++14)

转换函数可以继承,也可以是虚拟,但不可能静态派生类中的转换函数不会隐藏基类中的转换函数,除非它们正在转换为相同的类型。

转换函数可以是模板成员函数,例如,STD::AUTO[医]PTR<T>*操作员自动[医]PTR<Y>.见成员模板和模板参数推导适用的特别规则。

© cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

http://en.cppreference.com/w/cpp/language/cast[医]操作者