繁体   English   中英

在C ++中管理隐式类型转换

[英]Managing Implicit Type Conversion in C++

我正在研究做最近邻查询的代码。 有两个简单的想法可以作为用户查询搜索中数据的基础:

  • 最近的N指向空间中的给定点。
  • 给定距离内的所有点。

在我的代码中,Points被放入PointList,而PointList是一个容器,其工作是跟踪在搜索中找到的点。

现在我的PointList对象有一个构造函数:

PointList( unsigned int maxvals ); // #1

我想添加的下两个构造函数是:

PointList( float maxdist ); // #2
PointList( unsigned int maxvals, float maxdist ); // #3

我的问题是:我如何确保我的用户和C ++编译器将为PointList生成正确的构造函数并区分构造函数1和2? 我应该只实现#3并提供定义maxvals和maxdist的任意大值的常量吗? 另一个替代方案可能是编写另一个轻量级对象系统来管理将Points添加到列表中的逻辑,但这对于这样一个简单的想法来说就像是有点过分。

我真的试图让我的用户透明,这些用户大多是在没有正规教育的情况下学习过C ++的科学家。 谢谢!

为什么不使用工厂方法而不是构造函数? 工厂方法具有可自定义名称的优点。


static PointList createNearestValues(unsigned int maxvals) {}
static PointList createByDistance(float maxdist) {}

整数类型的重载分辨率发生在两个类别上,可以非常粗略地概括为

  • 升级:这是从小于int类型到intunsigned int ,具体取决于int是否可以存储源类型的所有值。
  • 转换:这是从任何整数类型到另一个整数类型的转换。

类似地,浮点类型的转换发生在两个类别上

  • 促销:这是从floatdouble的转换
  • 转换:这是从任何浮点类型到另一个浮点类型的转换

并且存在从整数到浮动或返回的转换。 这被归类为转化,而不是促销。 促销的排名优于转化,并且只需要促销,该情况将是首选。 因此,您可以使用以下构造函数

PointList( int maxVals );
PointList( unsigned int maxVals );
PointList( long maxVals );
PointList( unsigned long maxVals );

PointList( double maxDist );
PointList( long double maxDist );

对于任何整数类型,这应该选择第一组构造函数。 对于任何浮点类型,这应该选择第二组构造函数。 例如,如果传递一个int ,那么原始的两个构造函数很容易导致floatunsigned int之间的歧义。 对于另一个,两个参数构造函数,如果需要,可以使用您的解决方案。


也就是说,我也会使用工厂函数,因为我认为决定参数含义的类型是非常脆弱的。 大多数人都希望以下结果相等

PointList p(floor(1.5));
PointList u((int)1.5);

但这会导致不同的事态。

考虑使用true typedef 您的客户端代码需要付出更多努力,但保证您的正确性。

为第一个调用PointList(10),为第二个调用PointList(10f)。

对于第二个,您也可以使用10.0。

如果构造函数#1和#2存在,如果您插入的值是float或int,则将调用正确的构造函数,并且不应进行任何转换。 因此,只需确保您使用显式调用的数字类型(即1f和1)。 构造函数#3似乎不是一个选项,因为它不是真正必要的,只会混淆代码的用户。 如果您需要任何一个号码的默认值,您可以使用

PointList(int max, float max=VALUE)

PointList(float max, int max=VALUE)

再说一遍:在代码可读性方面,这似乎比代码更有害。

这要求对过载分辨率进行良好的阅读。

我肯定会使用显式构造函数。 在示例中,无符号整数不会隐式转换。

class A
{
public:
    explicit A(float f){}
    explicit A(int i){}
};

void test(){
    unsigned int uinteger(0);
    A a1(uinteger);        //Fails, does not allow implicit conversions

    A a2((float)uinteger); //OK, explicit conversion

    float f(0.0);
    A a3(f);               //OK

    int integer(0);
    A a4(integer);         //OK
}

错误消息很容易理解:

: error C2668: 'A::A' : ambiguous call to overloaded function
: could be 'A::A(int)'
: or       'A::A(float)'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM