Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板类中的类型转换运算符-无论显式_C++_Templates_Type Conversion - Fatal编程技术网

C++ 模板类中的类型转换运算符-无论显式

C++ 模板类中的类型转换运算符-无论显式,c++,templates,type-conversion,C++,Templates,Type Conversion,我有这个密码。大体上我想使用类型转换,但通过使用debug,我明白这一点 ob2=(Point2D)ob1 构造函数template Point2D(Point2D&ob)被调用,而与之前的explicit无关,即template explicit Point2D(Point2D&ob)为什么会发生这种情况?我希望调用操作符Point2D() template <class T> class Point2D { public: T x; T y; Point2

我有这个密码。大体上我想使用类型转换,但通过使用debug,我明白这一点
ob2=(Point2D)ob1

构造函数
template Point2D(Point2D&ob)
被调用,而与之前的
explicit
无关,即
template explicit Point2D(Point2D&ob)
为什么会发生这种情况?我希望调用
操作符Point2D()

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;
}
模板
类Point2D
{
公众:
tx;
T y;
点2d(T_x=0,T_y=0):x(x),y(y)
{
}
点2D(点2D和ob)
{
x=ob.x;
y=ob.y;
}
模板
点2D(点2D和ob)
{
x=ob.x;
y=ob.y;
}
模板
运算符Point2D()
{
返回点2d(x,y);
}
};
int main()
{
点2D ob1(10,10);
点2D ob2(20,20);
ob2=(点2D)ob1;
返回0;
}

如果是用户定义的转换函数,则无法进行模板参数推导:

template <class T1>
operator Point2D<T1>()
{
    return Point2D<T1>(x,y);
}
模板
运算符Point2D()
{
返回点2d(x,y);
}
编译器将如何推导模板参数
T1
?它不参与参数列表。仅当模板参数参与函数参数列表时,才能进行模板参数推断

由于模板参数推断是不可能的,因此将调用构造函数


希望对您有所帮助。

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

如果目标类型是(可能是cv限定的)类类型:

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

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

表达式
e
可以使用
static\u cast(e)
形式的
static\u cast(e)
显式转换为类型
T
,如果声明
T(e);
格式良好,对于一些发明的临时变量
T
(8.5)

[expr.cast]

由执行的转换

  • a
    const_cast
    (5.2.11)
  • a
    静态播放(5.2.9)
  • 一个
    static\u cast
    后接一个
    const\u cast
  • 重新解释铸件(5.2.10),或
  • 一个
    重新解释强制转换
    ,然后是一个
    常量转换
可以使用显式类型转换的强制转换表示法执行

另请注意
[class.conv.ctor]

显式构造函数与非显式构造函数一样构造对象,但仅在显式使用直接初始化语法(8.5)或强制转换(5.2.9,5.4)的情况下才这样做


为什么构造函数之前使用
explicit
调用?@exxxxxxxxxx:因为您已经编写了
ob2=(Point2D)ob1;
。请注意这部分
(Point2D)Ob1< /Cord>这是为什么调用构造函数的原因,尽管它被声明为“代码>显式< /COD>。如果您编写了代码> Obj2= Obj1<代码>,并将构造函数<代码>显式< /代码>。这将给出编译错误。BaloNy。转换运算符是C++中唯一的一个地方,其中考虑了重载类型和INF类型的返回类型。引用。请参见并为了支持@Ben的观点,请参见
§14.8.2.3[temp.Decrete.conv]p1
:“模板参数的推导是通过比较转换函数模板的返回类型(称为P;关于该类型的确定,请参见8.5、13.3.1.5和13.3.1.6)与转换结果所需的类型(称为A)来完成的。”如14.8.2.5所述。”