【问题标题】:Is it good practice to require the type in a class template to respond to a certain func?要求类模板中的类型响应某个函数是一种好习惯吗?
【发布时间】:2013-02-12 17:46:03
【问题描述】:

std 库在类模板中有类型,需要该类型覆盖某些 OPERATORS,例如,我们在 std::map 中使用的类型需要该类型支持

但是要求某些功能是好事吗?考虑这个愚蠢的例子

template <typename T> struct Foo {
  T t;
  Foo() {
    t.push_back(0);
  }
};

int main() {
  Foo<std::vector<int>> foo;
  return 0;
}

我已经创建了一个类模板 Foo,它的类型需要有一个 push_back 成员函数。这种设计对于 c++ 编码人员来说是否可以接受/通用?

【问题讨论】:

  • 您的代码完全没问题。但是,如果您仍然知道某种具有 push_back 函数的基类,并且如果您还知道与 Foo 一起使用的每个类都将从该基类扩展,请使用指向该基类的指针。 (例如,可以通过两种方式创建 COM 对象的 SafeRelease() 函数,例如 SafeRelease&lt;COMInterfaceType&gt;()SafeRelease(IUnknown * i),我更喜欢第二种方式)

标签: c++


【解决方案1】:

您所描述的称为模板策略(请参阅this),它是类或函数的完全合法且常见的设计模式。

【讨论】:

    【解决方案2】:

    当然。描述类模板时只需记录对模板参数的要求即可。

    请注意,在您的示例中,如果使用默认构造函数 Foo&lt;T&gt;()T 实际上只需要一个 push_back 函数。 (就语言而言。为了安全起见,您的要求可能会更严格。)

    如果您使用的是最新的编译器,您还可以使用static_assert 来确保大多数模板参数要求得到遵守,和/或在违反要求时使错误消息更清晰。

    【讨论】:

    • 能否请您详细说明static_assert,或许可以举个例子?这东西是 C++11 标准的一部分吗?
    【解决方案3】:

    是的,没关系。标准一直在这样做。例如,考虑std::back_inserter,正如您的示例所做的那样,它假定其模板类型实现了push_back 成员函数。虽然我们仍然没有concepts,但您最好记录您的要求。它还有助于以有意义的方式命名您的模板类型;所以你可能有template &lt;typename Container&gt;,而不是template &lt;typename T&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-15
      • 1970-01-01
      • 2019-10-06
      • 1970-01-01
      • 1970-01-01
      • 2019-04-30
      • 1970-01-01
      • 2020-02-06
      相关资源
      最近更新 更多