【问题标题】:Static polymorphism: How to define the interface?静态多态:如何定义接口?
【发布时间】:2015-04-27 03:20:56
【问题描述】:

下面是我理解为静态多态性的一个非常简单的例子。我不使用动态多态性的原因是我不想妨碍PROCESSORop 中的函数内联。

template <class PROCESSOR>
void op(PROCESSOR* proc){
    proc->doSomething(5);
    proc->doSomethingElse();
}

int main() {
    ProcessorY py;
    op<ProcessorY>(&py);
    return 0;
}

这个例子的问题是:没有明确定义PROCESSOR 必须定义什么功能。如果缺少一个,你只会得到一个编译错误。我认为这是一种糟糕的风格。

它还有一个非常实际的缺点:IDE 的在线帮助当然不能向您显示该对象上可用的功能。

定义PROCESSOR的公共接口的好/官方方法是什么?

【问题讨论】:

  • 首先,你为什么要指针?其次,定义由您在该函数模板的文档中给出。
  • 此外,IDE 不向您显示成员列表并不是一个非常重要的缺点。
  • 你只需要等待Concepts TS
  • @Columbo:指针,因为我不想按值传递可能巨大的 PROCESSOR。而且我个人喜欢 IDE 的建议,所以这个缺点是否显着只是个人喜好问题......
  • 为什么是指针而不是引用?

标签: c++ templates static-polymorphism


【解决方案1】:

对于 PROCESSOR 必须定义的方法没有明确的定义。如果缺少一个,你只会得到一个编译错误。我认为,这是一种糟糕的风格。

是的。它不是。可能是。视情况而定。

是的,如果您想以这种方式定义行为,您可能还想限制模板参数应该具有的内容。不幸的是,现在不可能“明确”地做到这一点。

您想要的是 constraints and concepts 功能,它本应作为 C++ 11 的一部分出现,但被延迟并且在 C++ 14 中仍然不可用。

但是,获得编译时错误通常是限制模板参数的最佳方法。例如,我们可以使用std library:

1) 迭代器。

C++ 库 defines 几种迭代器:forward_iteratorrandom_access_iterator 等。对于每种类型,都定义了一组属性和有效表达式,保证可用。如果你使用了迭代器,它与容器中的random_access_iterator 不完全兼容,需要random_access_iterator,你会在某些时候得到编译器错误(很可能,当使用解引用运算符([])时,这是迭代器所必需的类)。

2) 分配器。

std 库中的所有容器都使用分配器来执行内存分配/释放和对象构造。默认情况下,使用std::allocator。如果你想用你自己的交换它,你需要确保它拥有一切,std::allocator 保证拥有。否则会出现编译时错误。

所以,在我们得到概念之前,这是最好的和最广泛使用的解决方案。

【讨论】:

  • 可以通过实例化被检查类的预期成员函数指针来轻松模拟概念检查。
【解决方案2】:

首先,我认为您的静态多态示例没有问题。由于它是静态的,即编译时解析的,根据定义,它对其接口定义的要求不那么严格。

此外,不正确的代码不会编译/链接也是绝对合法的,尽管来自编译器的更清晰的错误消息会更好。

但是,如果您坚持定义接口,则可以通过以下方式重写您的示例:

template <class Type>
class Processor
{
public:
    void doSomething(int);
    void doSomethingElse();
};

template <class Type>
void op(Processor<Type>* proc){
    proc->doSomething(5);
    proc->doSomethingElse();
}

// specialization
template <>
class Processor<Type_Y>
{
    // implement the specialized methods
};

typedef Processor<Type_Y> ProcessorY;

int main() {
    ProcessorY py;
    op(&py);
    return 0;
}

【讨论】:

  • @Puppy 请详细说明这将如何改进答案。
  • 我认为@valdo 对解决此问题的可能解决方案给出了很好的答案。但我也会对 CRTP 的想法感兴趣。
  • 建议的Processor&lt;T&gt; 解决方案很糟糕。它严重降低了op() 的通用性,同时提供零收益。您的Processor&lt;Type_Y&gt; 专业化可能很容易不实现任何这些功能,然后您就处于与开始时完全相同的位置。
猜你喜欢
  • 1970-01-01
  • 2012-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-05
  • 2019-04-20
  • 1970-01-01
相关资源
最近更新 更多