Пардон, ассерту же нужен 0, который false.
Тогда стоит написать так: static_assert( !std::is_base_of<T, IQuackable>::value );
Это ведь не то же самое, что и: static_assert( std::is_base_of<IQuackable, T>::value );
Благодаря этому объему, вызов виртуального метода через vtable дольше лишь на одну операцию JMP. Иначе был бы список (а не таблица) виртуальных методов и это было бы крайне медленно.
Да ладно, разве мешают эти несколько десятков байт, когда речь идёт об ООП?
Насчёт расширяемости: Вполне себе расширяемо и переносимо. Можно сделать скрипт, который генерирует IGroup вплоть до 10 параметров, сохранить это чудо в IGroup.h и использовать без каких-либо изменений в любых проектах.
Насчёт скорости «вызовов по виртуальной таблице»: У меня такой вопрос давно уже зародился. Насколько вызов виртуального метода в C++ медленнее вызова простого метода? Насколько я понимаю добавляется лишь одна инструкция JMP и это не зависит от глубины наследования. Верно?
Использование шаблона IGroup позволяет при увеличении глубины вызова постепенно отбрасывать лишние интерфейсы. Иными словами, сперва у нас тип производный от A,B и C. Затем останется A,B и уже в самом конце вызовутся методы, которые принимают только A или только B.
Понятно. Мы говорим об одном и том же. Только у Вас подход заключается в том, чтобы проименовать группы интерфейсов явным образом. Я же, получается, предложил способ автоматизации этого процесса.
В начале статьи у меня код для сочетаний, а в конце для размещений. Просто одних сочетаний не достаточно, порядок наследования имеет значение. Не смотря на то, что речь идёт об интерфейсах, а не о полноценных классах (с полями).
Спасибо, поправлю термины выборки и сочетания, на сочетания и размещения. Запутался я немного)
Фактически шаблон IGroup делает это за вас. Он порождает дерево наследования от всевозможных комбинаций интерфейсов. Для интерфейсов A,B,C он породит родителей ABC, AB, AC, BA, BC, CA, CB, A, B, C.
class A {};
class B {};
class C {};
class Somebody : public A, public B, piblic C {};
class AC : public A, public C {}
void methodAC(AC * one)
{
}
int main()
{
Somebody * smb = new Somebody();
methodAC(smb); <u>// Ошибка компиляции ...</u>
}
А как потом в методе указать несколько интерфейсов у объекта? Если объект отнаследовать отинтерфейсов A, B и С, то как указать в типе параметра, что нужны только интерфейсы A и С?
Тогда стоит написать так:
static_assert( !std::is_base_of<T, IQuackable>::value );
Это ведь не то же самое, что и:
static_assert( std::is_base_of<IQuackable, T>::value );
Только порядок параметров обратный вроде должен быть: <T,IQuackable>
Да ладно, разве мешают эти несколько десятков байт, когда речь идёт об ООП?
Насчёт скорости «вызовов по виртуальной таблице»: У меня такой вопрос давно уже зародился. Насколько вызов виртуального метода в C++ медленнее вызова простого метода? Насколько я понимаю добавляется лишь одна инструкция JMP и это не зависит от глубины наследования. Верно?
Спасибо, поправлю термины выборки и сочетания, на сочетания и размещения. Запутался я немного)
void methodAB( {A*,B*} one );
или даже
void methodAB( {A,B} * one );