Size: a a a

2020 June 26

АК

Александр Караев... in pro.cxx
Побитый Кирпич
Дак это не статический полиморфизм уже
Вполне себе статический. Есть у меня type_list<A, B, C, D> и я для HasFoo<> делаю одно, для HasBar<> - другое и т.д.
источник

ПК

Побитый Кирпич... in pro.cxx
Александр Караев
Вполне себе статический. Есть у меня type_list<A, B, C, D> и я для HasFoo<> делаю одно, для HasBar<> - другое и т.д.
Тогда это не type_erasure :)
источник

ПК

Побитый Кирпич... in pro.cxx
Александр Караев
Полиморфизм на type erasure. Представь концепт
template <class T> concept HasFoo = requires (T& t) { t.foo(); }
У меня есть много типов, которые я единообразно обрабатываю. Для типов T, удовлетворяющих концепту, я вызываю foo(). Иначе - нет операции. Если я опечатаюсь в сигнатуре или названии, класс не сможет это определить и просто выкинет вызов "неправильной" foo
Да, теперь понял проблему
источник

АК

Александр Караев... in pro.cxx
Побитый Кирпич
Тогда это не type_erasure :)
ну type erasure я как пример привёл, прошу прощения за запутывание
источник

CD

Constantine Drozdov in pro.cxx
Александр Караев
Хочу перейти с виртуального интерфейса на статический. Если упрощенно, то вместо:

struct I { virtual void foo() { /* nothing */ } };
struct A : I { void foo() final { /* impl */ } };
struct B : I { /* no foo */ };


Иметь

struct A { void foo() { /* impl */ } };
struct B { /* no foo */ };


Я могу отличить A от B, проверив статически наличие void foo(), но есть нюанс - нет аналога final/override. То есть, если я ошибусь в сигнатуре функции или опечатаюсь в названии, компилятор меня не поправит. Есть способ решить эту проблему? Я думал в сторону каких-нибудь варнингов, которые будут реагировать на неиспользуемый метод. Компилятор - gcc.
Короче, или static_assert что foo есть, равносильный ": I" у тебя провалится, или пиши новый пример
источник

NP

Nikita Provotorov in pro.cxx
Побитый Кирпич
Какой наследник? Нет у нас наследования. Есть
template <typename SomeConcept>
void foo(SomeConcept some) {
 some.bar();
}

Работает со всем у чего есть bar
а окей, предлагаете вообще не связывать иерархией объекты
а что если для дефолтной реализации надо в приватные поля лезть?
источник

NP

Nikita Provotorov in pro.cxx
Nikita Provotorov
а окей, предлагаете вообще не связывать иерархией объекты
а что если для дефолтной реализации надо в приватные поля лезть?
хотя, можно наверное иметь методы bar и barDefault
источник

ПК

Побитый Кирпич... in pro.cxx
Nikita Provotorov
а окей, предлагаете вообще не связывать иерархией объекты
а что если для дефолтной реализации надо в приватные поля лезть?
С точки зрения функции foo приватных полей не существует, потребности такой возникнуть не может
источник

АК

Александр Караев... in pro.cxx
Constantine Drozdov
Короче, или static_assert что foo есть, равносильный ": I" у тебя провалится, или пиши новый пример
Ты прав. В случае наследования я указываю это как : I, а значит и в случае статического интерфейса я должен буду явно это указывать.

struct A {
 static_assert(implements_foo<A>);
 void foo() { };
}


Но как бы сократить эту запись.. Выше была озвучена идея с CRTP
источник

АК

Александр Караев... in pro.cxx
struct A : implements_foo<A> {
 void foo() {}
};
источник

CD

Constantine Drozdov in pro.cxx
Александр Караев
Ты прав. В случае наследования я указываю это как : I, а значит и в случае статического интерфейса я должен буду явно это указывать.

struct A {
 static_assert(implements_foo<A>);
 void foo() { };
}


Но как бы сократить эту запись.. Выше была озвучена идея с CRTP
Писать proposal на satisfies в декларации, наверное. А что ты хочешь сокращать-то?
источник

CD

Constantine Drozdov in pro.cxx
И в топку CRTP
источник

АК

Александр Караев... in pro.cxx
Constantine Drozdov
Писать proposal на satisfies в декларации, наверное. А что ты хочешь сокращать-то?
ну вот с виртуальными функциями я пишу : I и final. Всё, никаких букв лишних
источник

АК

Александр Караев... in pro.cxx
Constantine Drozdov
И в топку CRTP
почему?
источник

CD

Constantine Drozdov in pro.cxx
Александр Караев
ну вот с виртуальными функциями я пишу : I и final. Всё, никаких букв лишних
ну тут чуть буквеннее static_assert(IsI<A>), да
источник

CD

Constantine Drozdov in pro.cxx
он какой-то плохой :) не знаю, все случаи его использования постоянно выглядят костылями
источник

CD

Constantine Drozdov in pro.cxx
вот static_assert не выглядит, а CRTP базы для этого static_assert - выглядит
источник

ПК

Побитый Кирпич... in pro.cxx
Александр Караев
Ты прав. В случае наследования я указываю это как : I, а значит и в случае статического интерфейса я должен буду явно это указывать.

struct A {
 static_assert(implements_foo<A>);
 void foo() { };
}


Но как бы сократить эту запись.. Выше была озвучена идея с CRTP
Дак это вполне норм, если foo это концепт, аналогично  I
источник

АК

Александр Караев... in pro.cxx
Constantine Drozdov
вот static_assert не выглядит, а CRTP базы для этого static_assert - выглядит
а по-моему наоборот, я сразу при определении класса указываю, что он может и должен:

struct A : is_foo<A>, named<"A">, ... {};
источник

CD

Constantine Drozdov in pro.cxx
Александр Караев
а по-моему наоборот, я сразу при определении класса указываю, что он может и должен:

struct A : is_foo<A>, named<"A">, ... {};
определение класса еще не закончено его };
например, его внешний operator +
источник