【问题标题】:Specification for the type in a class using templates (instead of inheritance)使用模板(而不是继承)指定类中的类型
【发布时间】:2011-09-09 23:13:15
【问题描述】:

从一个类继承时,您只需查看层次结构即可了解对您施加的要求和限制。例如,您可以通过查看父类来找出需要定义哪些方法(纯虚拟)。如果一个人选择使用模板(如果它符合要求),那么事情就不那么清楚了。模板类的方法可能需要多个type 的方法。

我遇到了一个必须使用的复杂类。我不知道我的type(类/对象)应该有什么方法。我能找到的唯一方法是编译编译器会让我知道哪些方法是预期的。这就像从一个抽象类继承而不访问头文件。这有点麻烦,因为找出方法规范(签名)非常耗时。

现在该类的原始设计者可能已经放置了一些文档来说明预期会出现哪些方法及其签名,但我不禁想知道是否有一种方法可以让代码自我记录(或者已经,我不知道如何查看?)。编译和查看错误不能是唯一的方法,不是吗?

【问题讨论】:

  • AFAIK,没有办法解决这个问题,要么是文档错误,要么是编译器错误 - 选择你的毒药..
  • 您可以创建一个单独的测试 TU,其中仅包含模板、脚手架类 Foo 和显式实例化 template class MasterClass<Foo>;。这将使编译器实例化所有方法,并希望您可以使用诊断来确定您需要什么。不过,如果可以的话,重新设计模板以包含特征检查会更好。

标签: c++ templates


【解决方案1】:

您实质上是在描述C++0x concepts 将通过为程序员提供一种在编译时强制执行type 要求的方法来解决的问题。但是,由于时间限制,它于 2009 年 7 月被删除。

Boost 中有一个仅限库的解决方案,称为Concept Check Library (BCCL)。但是,there are differences 介于 BCCL 和 C++0x 概念之间。这是最接近我们当前语言概念的东西。

如果您不想使用 BCCL,那么文档是下一个最好的选择。

【讨论】:

    【解决方案2】:

    在 C++11 中有一个针对 concepts 的提议,可以解决这个问题:概念本质上是对模板参数必须满足的接口的描述。如果您现在需要,您可以从 Boost Concept Check Library 获得类似的功能,但是必须从一开始就设计一个类来使用概念断言,因此如果您有一个现有的库,那么您就不走运了。

    【讨论】:

      【解决方案3】:

      C++11 增加了 static_assert(在 C++03 中可以通过 BOOST_STATIC_ASSERT 来模拟)。现在,您可以编写许多将在编译时触发的此类断言,并向其中添加人类可读的文档,说明该断言触发的原因。根据您必须测试的工具(即 C++11 type_traits 或仅 boost.type_traits),您可以或多或少地使用它(也可以考虑使用 decltype 来检查做某些事情的可能性,可能结合 sizeof 技巧,很难笼统地说)

      【讨论】:

        【解决方案4】:

        使用组合和纯虚拟类可以避免这个问题。使用和理解接口更容易。理解实现如何实现接口更容易。单元测试更容易。

        struct B {
          virtual ~B() {}
          virtual void foo() const = 0;
          virtual void bar() const = 0;
        };
        
        struct D : public B {
          virtual ~D() {}
          virtual void foo() const {foo_thing.call();}
          virtual void bar() const {bar_thing.call();}
        private:
          some_foo_like_thing foo_thing;
          some_bar_like_thing bar_thing;
        };
        

        我希望谈论纯虚拟界面中应该和不应该是什么应该更容易,尽管里程可能会有所不同。 ;)

        欣赏某件事所需的信息越多,推理它的难度就越大。如果您的类依赖于其父类的实现,那么您基本上必须了解它以及它的每一个前辈。不仅是接口,还有实现。

        如果我要设计一种语言,实现继承甚至不是一种选择。

        【讨论】:

          猜你喜欢
          • 2020-06-26
          • 1970-01-01
          • 2011-10-04
          • 1970-01-01
          • 1970-01-01
          • 2018-05-23
          • 1970-01-01
          • 1970-01-01
          • 2010-10-22
          相关资源
          最近更新 更多