强制特定的typedefed类型

时间:2017-01-25 09:37:14

标签: c++

在图形中,所有几何数据类型都非常相似。为避免代码重复,但仍然对您正在做的事情有所了解,图形编码建议使用Vector类,其中包含PointsNormalsDirections的多个typedef。

因此,根据Normalize函数的签名(正如其所写),人们知道他正在处理Directions而不是PointsNormals。当然,没有什么可以阻止你传递PointNormal,因为它们都是Vectors(只是别名)。 我想知道是否有一种非开销方式强制程序员(即编译器警告级别4)传递显式声明为Direction的内容(不会在不同结构中多次复制Vector结构或继承多次来自Vector结构)如果没有,程序员需要做一个显式的强制转换(这只是一个noop)? (例如Haskell具有此功能)

struct Vector {

    // lots of methods

    float x, y, z;
};

typedef Vector Point;
typedef Vector Direction;
typedef Vector Normal;

Normal Normalize(const Direction &) {
    ...
}

3 个答案:

答案 0 :(得分:2)

你也可以使用模板,而不必重新实现所有构造函数:

template<typename tag>
struct Vector {
   ...
};

namespace tags {
    struct point;
    struct direction;
    struct normal;
}

typedef Vector<tags::point> Point;
typedef Vector<tags::direction> Direction;
typedef Vector<tags::normal> Normal;

Normal Normalize(const Direction &) {
    ...
}

但是请注意,虽然它没有运行时开销,但是它无法听到代码大小(用每个不同的标签实例化模板),以及编译时间开销(合并来自每个实例的所有弱符号)翻译单元成单个实例)。

你可以通过提供一个非模板化的基类来进行某种程度的缓解,这个基类可以实现&#34;实际工作&#34;。

答案 1 :(得分:1)

唯一的方法是你暗示你不喜欢,但这里是:

struct Point : Vector {};
struct Direction : Vector {};
struct Normal : Vector{};

除了需要定义和委派您可能拥有的任何构造函数之外,没有多少缺点。

对于C和具体使用GCC,这里是关于此主题的上一个问题:Warn if another typedef'd name of a type is used in an argument list

答案 2 :(得分:1)

当然你可以做到。你可以使用继承。只要您不使用虚拟方法,就不会产生运行时开销。

代码如下所示:

struct Vector3d {
    float x, y, z;
};

struct Direction :
    public Vector3d {

};

如果您有想要使用的特殊构造,可以使用声明将它们包含在子节点中。