使用typedef时的C ++模糊构造函数

问题描述 投票:1回答:3

在C ++中重载函数时,是否存在涉及模糊类型的以下问题的优雅解决方案?我想要两种不同的类型:“距离”和“角度”,它们在语义上意味着不同的东西,但实际上可能具有相同的类型。当尝试在C ++中执行此操作时,我遇到了函数重载的问题:

typedef float distance;
typedef float angle;

class Velocity {
public:
    Velocity(distance dx, distance dy) { /* impl */ }
    Velocity(angle theta, distance magnitude) { /* impl */ }
};

当我尝试编译它时,我得到“构造函数不能重新声明”。但是(由于某种原因,我无法弄清楚)当我在我的实际应用程序代码库中执行此操作时,类编译但后来我得到“调用'Velocity'的构造函数是不明确的”当我做这样的事情时:

distance dx;
distance dy;
Velocity v(dx, dy);

这个问题有没有优雅的解决方案?一个不令人满意的解决方案是仅更改其中一个数量的类型

typedef double distance;

但由于只有少数不同的浮点类型,因此显然无法扩展。我尝试过的另一个选择是使用模板

template <typename distance, typename angle>
class Velocity {
public:
    Velocity(distance dx, distance dy) : dx(dx), dy(dy) {  }
    Velocity(angle theta, distance magnitude) { }
};

但后来我得到“'Velocity'的多次重载实例化到相同的签名'void(float,float)'”如果我用相同的类型实例化它们。即使这样做仍然有点令人不满意,因为我必须在许多地方为Velocity类型添加模板参数。

c++ typedef
3个回答
3
投票

typedef不会创建新类型,它只是为具有不同名称的类型创建别名,并且可能在不同的名称空间中创建,类似于using

因此,你的构造函数都是有效的float, float

如果要创建实际的新类型,可以创建包含该类型的新结构或类。 C ++ chrono类型,如std::chrono::seconds包装整数。这样做也允许更具体的重载,例如你可能会说displacement = velocity * time,尽管这样做很快就会需要很多类型和运算符重载。

当你为floatdouble重载时也要小心,我肯定永远不会这样做,因为它们有不同的含义。考虑像01这样的文字会发生什么,或者像int这样的类型的隐式转换。


1
投票

您可以围绕距离和角度创建一个非常轻量级的包装,然后使用文字!

struct Distance {
    double value;
};
struct Angle {
    double value;
};

class Velocity {
   public:
    Velocity(Distance dx, Distance dy) { /* impl */ }
    Velocity(Angle theta, Distance magnitude) { /* impl */ }
};

然后,您可以在构造Velocity时包装值:

// Create by distance
Velocity v1(Distance{5.0}, Distance{10.0}); 
// Create by angle
Velocity v2(Angle{1.5}, Distance{1.0}); 

我们还可以提供用户定义的文字,以便您可以像这样编写v1v2

Velocity v1(5.0_meters, 10.0_meters);
Velocity v2(60.0_degrees, 10.0_meters);

编写用户定义的文字非常简单:

Distance operator ""_meters(double value) {
    return Distance{value}; 
}
Angle operator ""_degrees(double value) {
    return Angle{value / 180.0 * PI}; 
}

0
投票

是的,您需要不同类型才能拥有重载。

一种解决方案是通过更改函数名称来避免重载。

另一种是通过创建包裹浮动的classstruct来创建自定义类型。

然后,您可以重载某些运算符以实现所需的行为,但在我看来,最好更改函数的名称

© www.soinside.com 2019 - 2024. All rights reserved.