5

下面是我理解的静态多态性的一个非常简单的例子。我不使用动态多态性的原因是我不想阻止 in 函数的内PROCESSORop

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

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

这个例子的问题是:没有明确定义 aPROCESSOR必须定义什么函数。如果缺少一个,你只会得到一个编译错误。我认为这是不好的风格。

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

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

4

2 回答 2

3

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

这是。它不是。可能是。这取决于。

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

您想要的是约束和概念功能,它应该作为 C++ 11 的一部分出现,但被延迟了,并且在 C++ 14 中仍然不可用。

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

1) 迭代器。

C++ 库定义了几种类型的迭代器:forward_iteratorrandom_access_iterator其他。对于每种类型,都定义了一组属性和有效表达式,保证可用。random_access_iterator如果您使用了与容器中不完全兼容的迭代器,则random_access_iterator在某些时候会出现编译器错误(很可能,在使用此迭代器类中需要的解引用运算符([])时)。

2) 分配器。

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

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

于 2015-04-26T12:03:05.563 回答
1

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

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

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

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;
}
于 2015-04-26T11:46:17.910 回答