模板类中的类型转换运算符 - 无论显式如何都调用

Type conversion operator in template class - invoked regardless of explicit

本文关键字:调用 运算符 类型转换      更新时间:2023-10-16

我有这个代码。总的来说,我想使用类型转换,但是使用调试时,我明白在这一行中 ob2=(Point2D<double>)ob1;

无论之前explicit如何,都会调用构造函数template <class T1> Point2D(Point2D<T1>& ob),即 template <class T1> explicit Point2D(Point2D<T1>& ob) 为什么会这样?我希望调用operator Point2D<T1>()

template <class T>
class Point2D
{
public:
    T x;
    T y;
    Point2D(T _x=0,T _y=0):x(_x),y(_y)
    {
    }
    Point2D(Point2D& ob)
    {
        x=ob.x;
        y=ob.y;
    }
    template <class T1>
    Point2D(Point2D<T1>& ob)
    {
        x=ob.x;
        y=ob.y;
    }
    template <class T1>
    operator Point2D<T1>()
    {
        return Point2D<T1>(x,y);
    }
};
int main()
{
    Point2D<int> ob1(10,10);
    Point2D<double> ob2(20,20);
    ob2=(Point2D<double>)ob1;
    return 0;
}

该标准的第 [dcl.init] 节指定在初始化期间首选构造函数:

如果目标类型是(可能符合 cv 条件的(类类型:

  • 如果初始化是直接初始化,或者如果是复制初始化,其中源类型的 cv 非限定版本与目标类的类相同,或者是目标类的派生类,则考虑构造函数。枚举适用的构造函数 (13.3.1.3(,并通过重载解析 (13.3( 选择最佳构造函数。调用如此选择的构造函数来初始化对象,并使用初始值设定项表达式或表达式列表作为其参数。如果未应用构造函数,或者重载解析不明确,则初始化格式不正确。
  • 否则(即,对于剩余的复制初始化情况(,如 13.3.1.4 中所述枚举可以从源类型转换为目标类型或(使用转换函数时(转换为其派生类的用户定义的转换序列,并通过重载分辨率 (13.3( 选择最佳转换序列。如果转换无法完成或不明确,则初始化格式不正确。 使用初始值设定项表达式作为其参数调用所选函数;如果函数是构造函数,则调用将初始化目标类型的 CV 非限定版本的临时版本。临时是原则。然后,调用的结果(构造函数情况的临时结果(用于根据上述规则直接初始化作为复制初始化目标的对象。 在某些情况下,允许实现通过将中间结果直接构造到正在初始化的对象中来消除此直接初始化中固有的复制;参见 12.2、12.8。

此规则意味着仅当构造函数不适用时,才会考虑用户定义的转换序列。

强制转换使用与初始化相同的规则,请参阅[expr.static.cast]

对于

某些发明的临时变量t (8.5(,可以使用形式static_cast static_cast<T>(e)声明T t(e);格式正确,则可以使用表单显式转换为表达式e T类型。

[expr.cast]

执行的转换

  • a const_cast(5.2.11(,
  • a static_cast(5.2.9(,
  • 一个static_cast后跟一个const_cast
  • a reinterpret_cast (5.2.10(,或
  • 一个reinterpret_cast后跟一个const_cast

可以使用显式类型转换的强制转换表示法来执行。

另请注意[class.conv.ctor]

显式构造函数

像非显式构造函数一样构造对象,但仅在显式使用直接初始化语法 (8.5( 或显式使用强制转换 (5.2.9、5.4( 的情况下执行此操作。

用户自定义转换函数的情况下,模板参数推导是不可能的:

template <class T1>
operator Point2D<T1>()
{
    return Point2D<T1>(x,y);
}

编译器将如何推导模板参数T1?它不参与参数列表。只有当模板参数参与函数参数列表时,才能进行模板参数推导。

由于无法推导模板参数,因此将改为调用构造函数。

希望有帮助。