概念与接口有何不同?

use*_*812 22 c++ generics templates c++11 c++-concepts

概念(即最近从C++ 0x标准中删除的那些)与Java等语言中的接口有何不同?

Ara*_*raK 26

概念用于编译时多态,这意味着参数通用代码.接口用于运行时多态.

您必须在实现Concept时实现接口.不同之处在于您不必明确表示您正在实施Concept.如果所需的接口匹配则没有问题.在接口的情况下,即使你实现了所有必需的功能,你也要兴奋地说你正在实现它!


我会尽力澄清我的答案:)

想象一下,您正在设计一个容器,它接受任何具有size成员函数的类型.我们将Concept形式化并称之为HasSize,当然我们应该在其他地方定义它,但这不再是一个例子.

template <class HasSize>
class Container
{
  HasSize[10]; // just an example don't take it seriously :)
 // elements MUST have size member function!
};
Run Code Online (Sandbox Code Playgroud)

然后,想象一下我们正在创建一个Container的实例,我们称之为myShapes,Shape是一个基类,它定义了size成员函数.Square和Circle就是它的孩子.如果Shape未定义大小,则应生成错误.

Container<Shape> myShapes;

if(/* some condition*/)
    myShapes.add(Square());
else
    myShapes.add(Circle());
Run Code Online (Sandbox Code Playgroud)

我希望你看到在编译时可以对HasSize检查Shape ,没有理由在运行时进行检查.与myShapes的元素不同,我们可以定义一个操作它们的函数:

void doSomething(Shape* shape)
{
    if(/* shape is a Circle*/)
        // cast then do something with the circle.
    else if( /* shape is a Square */)
        // cast then do something with the square.
}
Run Code Online (Sandbox Code Playgroud)

在这个函数中,你无法知道在圆形或正方形运行之前会传递什么!

它们是用于类似工作的两个工具,虽然Interface或者你称之为 - 在运行时可以完成与Concepts几乎相同的工作,但是你会失去编译时检查和优化的所有好处!

  • 为什么说接口是为了运行时多态性呢?接口约束在编译时检查。你指的是vtable查找吗?此外,您的“doSomething”函数并没有真正显示接口和概念的不同之处,而且似乎有点无关紧要。您将如何用概念以不同的方式完成“doSomething”?为什么不使用多态性而不是 if-else 链和强制转换呢? (2认同)

Kla*_*aim 7

概念类似于模板的类型(类):它仅用于语言的通用编程方面.

这样,它并不意味着替换接口类(假设您的意思是抽象类或C#或Java接口的其他C++等效实现),因为它仅用于检查模板参数中使用的类型以匹配特定要求.类型检查仅在编译时完成,就像生成所有模板代码一样,而接口类对运行时执行有影响.