【问题标题】:How to combine templates with enums in C++?如何在 C++ 中将模板与枚举结合起来?
【发布时间】:2010-10-19 14:48:34
【问题描述】:

C++ 编程语言中有一个庞大的特性集合,可以对数据类型进行严格控制。经常有人会用模板系统塑造他的代码,以实现最充分的功能,同时保证在其中正确的类型保存和操作的灵活性。较少使用枚举用于此目的,因为它们允许为数据定义明确的可能性,并且没有直接的方法来验证类型的正确性。

所以我们所拥有的是允许函数和类与泛型类型一起操作而无需为每个类型重写的模板;和枚举,提供预期类型的​​直接使用。

是否可以为使用枚举作为模型的类定义受限模板架构?模板化方法如何使用枚举类型以及何时有用?

我的最后一个问题是:如何将模板和枚举类型结合起来,并在抽象数据设计中一起使用?

例如,假设您正在尝试创建一个数据容器,您希望在类中的枚举中定义类型:

template <typename T>
class element
{
public:
  enum type { text_type, widget_type, image_type };

  ...
private:
  type node_type;

};

您还定义了class element 中存在的每种类型:

class text;
class widget;
class image;

创建一个元素,你想指定它的内容类型(文本、小部件或图像),所以你通过模板参数传递它。

if (node_type == text_type) do_something();

在 Java 中,List&lt;? extends T&gt; 隐含地说明了可以将什么类型的类用作模板参数。可以使用枚举在 C++ 中完成吗?如何在语句中使用枚举类型?

问题:我想知道如何通过枚举类型限制模板的行为,以确保仅使用这些类型,并使用传统方式定位代码使用枚举。

【问题讨论】:

  • 你说的是什么意思“是否可以为使用枚举作为模型的类定义受限模板架构?”
  • 枚举行为问题是否源于 Java 使用?
  • @Rizo,你需要澄清你的问题。正如发布的那样,它太模糊了。尝试发布一些代码以显示您正在尝试做的事情
  • @Rizo:请在您的问题中添加一个潜在的用例(以伪代码形式)。
  • @Rizo:你说的是Java List&lt;? extends T&gt;泛型范式的等价物吗?

标签: c++ templates enums language-features


【解决方案1】:

@UncleBens 说明的类型特征习语是解决此问题的常用方法。

您也可以使用整数或枚举类型的static const 成员将信息附加到类。

#include <iostream>

enum color { red, green, blue };

struct x {
    static const color c = red;
};

template< color c >
struct thing;

template<>
struct thing< red > {
    thing() { std::cout << "red\n"; }
};

int main() {
    thing< x::c >();
}

【讨论】:

  • 我猜这是否可以用来选择模板类型。例如使用 matrix => 会产生一个 4x4 浮点矩阵,(并且浮点类型只是一个枚举值)
  • @DarioOO 你当然可以安排,但matrix&lt; float, 4, 4 &gt; 不是更清楚吗?
  • 当然:) 只是因为在我的例子中使用 enum 使得 API 更加简单。我只有有限数量的向量类型(float2、float3、ubyte3)等,所以我只为我支持的类型提供枚举,而不是检查该类型是否具有正确的长度
【解决方案2】:

如果您不需要使用枚举,我相信您可以使用标准库中使用的类似技术对迭代器进行分类。

class text {};
class widget {};
class image {};

struct text_type_tag {};
struct widget_type_tag {};
struct image_type_tag {};

template <class T>
struct element_traits;

template <>
struct element_traits<text>
{
    typedef text_type_tag category;
};

template <>
struct element_traits<widget>
{
    typedef widget_type_tag category;
};

template <>
struct element_traits<image>
{
    typedef image_type_tag category;
};

//add specializations for any other type you want to categorize

//a template that only works with widget types
template <class Widget>
void foo_implementation(Widget w, widget_type_tag);

template <class Widget>
void foo(Widget w)
{
    foo_implementation(w, typename element_traits<Widget>::category());
}

int main()
{
    foo(widget());
    foo(10);  //error, element_traits not specialized for int (incomplete)
    foo(image()); //error, no matching call for foo_implementation(image, image_type_tag);
}

还有一种可能性:为其他类别的元素重载foo_implementation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 2018-01-15
    • 2020-09-11
    相关资源
    最近更新 更多