微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C++:使用初始化列表进行缩小转换

如何解决C++:使用初始化列表进行缩小转换

C++11,使用 Visual Studio 2019。

我有一个 Vector2D 类,有 2 个 floatxy。我正在使用带有 4 个 RECT 的旧类 longlefttoprightbottom

一个函数需要一个 Vector2D 作为参数:

void DrawLine(Vector2D v1,Vector2D v2);

我希望编译以下代码时不会出现缩小转换错误 (C2398):

struct RECT
{
    LONG left;
    LONG top;
    LONG right;
    LONG bottom;
};

struct Vector2D
{
    float x;
    float y;
};
    
void DrawLine(Vector2D v1,Vector2D v2)
{
    // stuff
}
    
...
    
void main(){
    RECT r = { 10,10,100,100 };
    DrawLine({r.left,r.top},{r.right,r.bottom});
}

我尝试将带有 std::initializer_list<long> 的构造函数添加Vector2D,但我仍然收到 C2398 错误。参考一个类似的问题,初始化列表不允许以这种方式缩小范围。

我可以尝试其他任何方法吗?失去精度等对我来说不是问题。 我可以做到:

DrawLine({static_cast<float>(r.left),static_cast<float>(r.top)},{static_cast<float>(r.right),static_cast<float>(r.bottom)});

但我太懒了,每次都这样做,而且代码很混乱。

解决方法

正如@Blindly 在评论中提到的,只需给 Vector2D() 一个接受 2 LONG 作为输入的构造函数,例如:

struct Vector2D
{
    float x;
    float y;

    Vector2D(float x,float y) : x(x),y(y) {}
    Vector2D(LONG x,LONG y) : x(static_cast<float>(x)),y(static_cast<float>(y)) {}
};

然后您对 DrawLine({r.left,r.top},{r.right,r.bottom}) 的调用将按预期工作。

Demo

,

感谢 HolyBlackCat 的想法,我在 Vector2D 中使用了以下构造函数:

template<typename T,typename U>
Vector2D(const T& tx,const U& ty)
{
    x = static_cast<decltype(x)>(tx);
    y = static_cast<decltype(y)>(ty);
}

我知道这不是关于隐式收缩等的最佳实践,但它让编译器只用几行代码就可以从所有算术类型中进行转换。

,

但是我太懒了,每次都做这个

好吧,你正在做的是隐式缩小,并失去精度,所以没有告诉编译器你可以明确地(通过强制转换)会产生一个警告(你可以关闭,但可能不应该)。

但那是因为您使用了隐式构造。没有什么能阻止你向你的向量类添加合适的构造函数,一个接受浮点数,一个接受长整数,并且后一个构造函数中的显式转换只完成一次。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。