Ответ 1
Понятия предназначены для полиморфизма времени компиляции, что означает параметрический общий код. Интерфейсы предназначены для полиморфизма во время выполнения.
Вы должны реализовать интерфейс при реализации Концепции. Разница в том, что вам не нужно явно указывать, что вы реализуете концепцию. Если соответствующий интерфейс согласован, то проблем нет. В случае интерфейсов, даже если вы внедрили all требуемые функции, вы должны возбудить, что вы его реализуете!
Я попытаюсь уточнить свой ответ:)
Представьте, что вы проектируете контейнер, который принимает любой тип, который имеет функцию члена размер. Мы формализуем концепцию и называем ее HasSize, конечно, мы должны определить ее в другом месте, но это не более пример.
template <class HasSize>
class Container
{
HasSize[10]; // just an example don't take it seriously :)
// elements MUST have size member function!
};
Затем представьте, что мы создаем экземпляр нашего Контейнера и называем его myShapes, Shape является базовым классом и определяет размер. > функция-член. Квадрат и Круг - просто дети. Если форма не определяла размер, тогда необходимо создать ошибку.
Container<Shape> myShapes;
if(/* some condition*/)
myShapes.add(Square());
else
myShapes.add(Circle());
Надеюсь, вы увидите, что во время компиляции Shape можно проверить на HasSize, нет никаких оснований делать проверку во время выполнения. В отличие от элементов 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.
}
В этой функции вы не можете знать, что будет передано до времени выполнения Circle или Square!
Это два инструмента для аналогичной работы, хотя интерфейс или то, что вы им называете, может выполнять почти ту же работу Concepts во время выполнения, но вы теряете все преимущества проверки времени и оптимизации времени компиляции.