c++ - C++ 中基于枚举值的专用类构造函数

标签 c++ class templates

我需要创建一个描述一组数学形状的类。假设我想要 SphereCylinderAABBOBB。对于这些,我将创建一个 enum 来表示它们,并希望用户传递他们所需的形状类型并提供正确的输入。例如:

// Shapes.h
enum ShapeType { Sphere, Cylinder, AABB, OBB, Count};

class Shape {
public: 
  Shape(ShapeType type, const float r, const float hl, const Vector3& minExtend, const Vector3& maxExtend);

private:
  ShapeType m_Type;
  float m_Radius;       // for Sphere and Cylinder end caps
  float m_halfLength;   // for Cylinders
  Vector3 m_minExtend;  // for AABB or OBB
  Vector3 m_maxExtend;  // for AABB or OBB
  Entity m_Parent;      // has position, orientation and scale; 
}

不理想的是,在创建 Shape 实例时,用户被迫提供所有变量,即使他们不需要。例如,Sphere 不会关心半长。因此我的问题是 - 有没有一种方法可以根据 enum 值专门化我的构造函数?例如下面的伪代码:

// Shapes.h
enum ShapeType { Sphere, Cylinder, AABB, OBB, Count};

class Shape {
public: 
  Shape(ShapeType type = Sphere, const float r);
  Shape(ShapeType type = Cylinder, const float r, const float hl);
  Shape(ShapeType type = AABB, const Vector3& minExtend, const Vector3& maxExtend);
  Shape(ShapeType type = OBB, const Vector3& minExtend, const Vector3& maxExtend);

// ... same as above

注意,我真的不想在这里使用继承并创建一系列形状,因为此类实际上只是用于在发送到另一个进程之前保存一些原始数据。

最佳答案

如果您提供形状类型作为参数,则无法执行此操作。毕竟给了

float r = 5;
ShapeType shape = getRandomShape(); // determine the shape to use via random number generation
Shape shape(shape, r);

编译器无法判断shape是否为ShapeType::Sphere;该值在运行时确定。

如果您始终直接提供常量,则可以通过使用maker参数来实现与此类似的效果,为编译器提供具有ShapeType类型的模板参数的对象,以便能够确定使用重载解析正确的构造函数。

template<ShapeType>
struct ShapeTypeTag
{};

inline constexpr ShapeTypeTag<ShapeType::Sphere> SphereType;

class Shape {
public: 
    Shape(ShapeTypeTag<Sphere>, const float r);
    Shape(ShapeTypeTag<Cylinder>, const float r, const float hl);
    Shape(ShapeTypeTag<AABB>, const Vector3& minExtend, const Vector3& maxExtend);
    Shape(ShapeTypeTag<OBB>, const Vector3& minExtend, const Vector3& maxExtend);
};

...

Shape shape(SphereType, 5);

我首选的实现方法是在 Shape 中创建单独的静态成员函数来创建每种形状类型:

class Shape {
    template<ShapeType>
    ShapeTypeTag
    {
    };  

    Shape(const float r);
    Shape(const float r, const float hl);
    Shape(ShapeTypeTag<AABB>, const Vector3& minExtend, const Vector3& maxExtend);
    Shape(ShapeTypeTag<OBB>, const Vector3& minExtend, const Vector3& maxExtend);

public:

    static Shape createSphere(float r)
    {
        return r;
    }

    static Shape createCylinder(float r, float hl)
    {
        return { r, hl };
    }

    static Shape createAABB(const Vector3& minExtend, const Vector3& maxExtend)
    {
        return { ShapeTypeTag<ShapeType::AABB>{}, minExtend, maxExtend };
    }

    static Shape createOBB(const Vector3& minExtend, const Vector3& maxExtend)
    {
        return { ShapeTypeTag<ShapeType::OBB>{}, minExtend, maxExtend };
    }
};

...

Shape shape = Shape::createSphere(5);

关于c++ - C++ 中基于枚举值的专用类构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76792303/

相关文章:

c++ - 模板类的可变成员函数

c++ - 编译netbean时出错

c++ - 通过 std::visit 从 std::variant 中的可能类型返回值

python - 从另一个文件中的类导入函数?

c++ - 模板类不同的返回类型取决于类参数

c++ - 通用回调

c++ - [C++] 在此代码之前不存在的析构函数中抛出的内存错误。尝试制作一个新的动态数组并填充它

c++ - 为什么无法在 C++ 中撤消 'using'?

ruby - 如何从扩展类或包含的模块中的类方法访问父类的字符串名称

c++ - 具有来自不同 header 的模板类的类将无法编译