All streams
Search
Write a publication
Pull to refresh
173
0
Антон Буков @k06a

Software Engineer

Send message
Пардон, ассерту же нужен 0, который false.
Тогда стоит написать так:
static_assert( !std::is_base_of<T, IQuackable>::value );
Это ведь не то же самое, что и:
static_assert( std::is_base_of<IQuackable, T>::value );
Спасибо за этот пример, добавил Ваш коммент в избранное.
Только порядок параметров обратный вроде должен быть: <T,IQuackable>
Благодаря этому объему, вызов виртуального метода через vtable дольше лишь на одну операцию JMP. Иначе был бы список (а не таблица) виртуальных методов и это было бы крайне медленно.

Да ладно, разве мешают эти несколько десятков байт, когда речь идёт об ООП?
Насчёт расширяемости: Вполне себе расширяемо и переносимо. Можно сделать скрипт, который генерирует IGroup вплоть до 10 параметров, сохранить это чудо в IGroup.h и использовать без каких-либо изменений в любых проектах.

Насчёт скорости «вызовов по виртуальной таблице»: У меня такой вопрос давно уже зародился. Насколько вызов виртуального метода в C++ медленнее вызова простого метода? Насколько я понимаю добавляется лишь одна инструкция JMP и это не зависит от глубины наследования. Верно?
Ну так а на каком этапе сработает assert? На этапе выполнения… А тут ошибки детектируются на этапе компиляции.
Физически получится наследование от 3-х базовых интерфейсов. Не более того. Для того и есть слово virtual.
Использование шаблона IGroup позволяет при увеличении глубины вызова постепенно отбрасывать лишние интерфейсы. Иными словами, сперва у нас тип производный от A,B и C. Затем останется A,B и уже в самом конце вызовутся методы, которые принимают только A или только B.
Спасибо за пример, прокачаю свои знания буста.
Не знал что where можно использовать в объявлении методов. Спасибо за информацию.
Возможно стоило поместить в блог «Ненормальное программирование?»)
Понятно. Мы говорим об одном и том же. Только у Вас подход заключается в том, чтобы проименовать группы интерфейсов явным образом. Я же, получается, предложил способ автоматизации этого процесса.
В начале статьи у меня код для сочетаний, а в конце для размещений. Просто одних сочетаний не достаточно, порядок наследования имеет значение. Не смотря на то, что речь идёт об интерфейсах, а не о полноценных классах (с полями).

Спасибо, поправлю термины выборки и сочетания, на сочетания и размещения. Запутался я немного)
Не совсем, в языке С++ могла бы быть конструкция типа такой:
void methodAB( {A*,B*} one );
или даже
void methodAB( {A,B} * one );
Фактически шаблон 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 и С?
Я думал это новая акция вконтакта «А кого из друзей стесняешься ты??»)))
Спасибо тем, кто вывел меня из минуса. Пора готовить статьи, чтоб хоть было что выложить как будет возможность)

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity