Size: a a a

2021 February 18

IZ

Ilia Zviagin in pro.cxx
Bogdan  перенесено...
источник

ИШ

Илья Шишков... in pro.cxx
Привет! Есть два класса с похожими шаблонными методами.
struct A {
 template<typename... Args>
 void Do(int x, string s, Args&& args...);
};

struct B {
 template <typename... Args>
 void Do(Args&& args...);
};


И есть функции, которые делают одно и то же, но внутри себя вызывают либо A::Do, либо B::Do. Из-за этого их приходится реализовывать дважды:

void DoSomething(char c, bool q, int x, string s, A& a);
void DoSomething(char c, bool q, B& b);


Хочется спрятать A и B за общим интерфейсом, чтобы не дулировать код функций DoSomething. Всё, что удалось придумать — это сделать DoSomething шаблонной и передавать туда некое подобие лямбды, которая дёргает либо A, либо B.

Но из-за этого пришлось код DoSomething перетащить из cpp-файла в заголовчный. А вот как сделать так, чтобы реализации остались в cpp-файле, пока придумать не удалось.

У вас идеи?
источник

AT

Alexander Tulikov in pro.cxx
Илья Шишков
Привет! Есть два класса с похожими шаблонными методами.
struct A {
 template<typename... Args>
 void Do(int x, string s, Args&& args...);
};

struct B {
 template <typename... Args>
 void Do(Args&& args...);
};


И есть функции, которые делают одно и то же, но внутри себя вызывают либо A::Do, либо B::Do. Из-за этого их приходится реализовывать дважды:

void DoSomething(char c, bool q, int x, string s, A& a);
void DoSomething(char c, bool q, B& b);


Хочется спрятать A и B за общим интерфейсом, чтобы не дулировать код функций DoSomething. Всё, что удалось придумать — это сделать DoSomething шаблонной и передавать туда некое подобие лямбды, которая дёргает либо A, либо B.

Но из-за этого пришлось код DoSomething перетащить из cpp-файла в заголовчный. А вот как сделать так, чтобы реализации остались в cpp-файле, пока придумать не удалось.

У вас идеи?
Сделать обёртку над A, которая будет хранить в себе int x, string s?
источник

IZ

Ilia Zviagin in pro.cxx
Илья Шишков
Привет! Есть два класса с похожими шаблонными методами.
struct A {
 template<typename... Args>
 void Do(int x, string s, Args&& args...);
};

struct B {
 template <typename... Args>
 void Do(Args&& args...);
};


И есть функции, которые делают одно и то же, но внутри себя вызывают либо A::Do, либо B::Do. Из-за этого их приходится реализовывать дважды:

void DoSomething(char c, bool q, int x, string s, A& a);
void DoSomething(char c, bool q, B& b);


Хочется спрятать A и B за общим интерфейсом, чтобы не дулировать код функций DoSomething. Всё, что удалось придумать — это сделать DoSomething шаблонной и передавать туда некое подобие лямбды, которая дёргает либо A, либо B.

Но из-за этого пришлось код DoSomething перетащить из cpp-файла в заголовчный. А вот как сделать так, чтобы реализации остались в cpp-файле, пока придумать не удалось.

У вас идеи?
выделить общий интерфейсл для A , B, в нём сделать метод, без или с двумя параметрами c, q , добавить методы по установке дополнительных параетров ( x, s)
реализовать методы в классах A, B,  перевызывая соотв. Do
Потом вместо DoSometing вызывать этот новый метод через общий интерфейс
источник

w

wonder in pro.cxx
Илья Шишков
Привет! Есть два класса с похожими шаблонными методами.
struct A {
 template<typename... Args>
 void Do(int x, string s, Args&& args...);
};

struct B {
 template <typename... Args>
 void Do(Args&& args...);
};


И есть функции, которые делают одно и то же, но внутри себя вызывают либо A::Do, либо B::Do. Из-за этого их приходится реализовывать дважды:

void DoSomething(char c, bool q, int x, string s, A& a);
void DoSomething(char c, bool q, B& b);


Хочется спрятать A и B за общим интерфейсом, чтобы не дулировать код функций DoSomething. Всё, что удалось придумать — это сделать DoSomething шаблонной и передавать туда некое подобие лямбды, которая дёргает либо A, либо B.

Но из-за этого пришлось код DoSomething перетащить из cpp-файла в заголовчный. А вот как сделать так, чтобы реализации остались в cpp-файле, пока придумать не удалось.

У вас идеи?
Сделать общего родителя и воспользоваться виртуальными функциями с полиморфизмом. Передавая указатель на объект класса в функцию. Тогда реализовывать логику функции нужно будет один раз, но принимать она будет по указателю
источник

ИШ

Илья Шишков... in pro.cxx
wonder
Сделать общего родителя и воспользоваться виртуальными функциями с полиморфизмом. Передавая указатель на объект класса в функцию. Тогда реализовывать логику функции нужно будет один раз, но принимать она будет по указателю
Я тоже так сначала подумал, но метод Do принимает paramter-pack — для него нельзя сделать виртуальный метод (
источник

w

wonder in pro.cxx
Илья Шишков
Я тоже так сначала подумал, но метод Do принимает paramter-pack — для него нельзя сделать виртуальный метод (
Что вы имеете ввиду под parameter-pack? Не совсем понял о чем вы
источник

MK

Mikhail Kalugin in pro.cxx
wonder
Что вы имеете ввиду под parameter-pack? Не совсем понял о чем вы
Там шаблон и пак с параметрами на входе метода Do...
источник

MK

Mikhail Kalugin in pro.cxx
Правда, если он реализует явно два из возможных вариантов этого шаблона и все, зачем вообще шаблон?
источник

ИШ

Илья Шишков... in pro.cxx
wonder
Что вы имеете ввиду под parameter-pack? Не совсем понял о чем вы
```
struct B {
 template <typename... Args>
 void Do(Args&& args...);
};
```

ПРоизвольное количество аргументов в методе Do -- это paramter pack
источник

w

wonder in pro.cxx
Выше человек правильно рассуждает. Попробуйте обратить больше внимания на семантику и ваше проектирование. Может быть что-то мешает вам найти правильный вариант и так как в чате сокращенная версия мы не можем вам помочь в полной мере
источник

AD

Andrey Davydov in pro.cxx
Илья Шишков
Привет! Есть два класса с похожими шаблонными методами.
struct A {
 template<typename... Args>
 void Do(int x, string s, Args&& args...);
};

struct B {
 template <typename... Args>
 void Do(Args&& args...);
};


И есть функции, которые делают одно и то же, но внутри себя вызывают либо A::Do, либо B::Do. Из-за этого их приходится реализовывать дважды:

void DoSomething(char c, bool q, int x, string s, A& a);
void DoSomething(char c, bool q, B& b);


Хочется спрятать A и B за общим интерфейсом, чтобы не дулировать код функций DoSomething. Всё, что удалось придумать — это сделать DoSomething шаблонной и передавать туда некое подобие лямбды, которая дёргает либо A, либо B.

Но из-за этого пришлось код DoSomething перетащить из cpp-файла в заголовчный. А вот как сделать так, чтобы реализации остались в cpp-файле, пока придумать не удалось.

У вас идеи?
> сделать DoSomething шаблонной и передавать туда некое подобие лямбды
передавать std::function
источник

ИШ

Илья Шишков... in pro.cxx
Всем спасибо за идеи — буду переваривать
источник

IZ

Ilia Zviagin in pro.cxx
wonder
Что вы имеете ввиду под parameter-pack? Не совсем понял о чем вы
Приём есть такой для убирания многочисленных параметов методов — параметры складываются в какую-то полиморфную структуру типа
map< string , variant > и передаются списком
источник

ИШ

Илья Шишков... in pro.cxx
Ilia Zviagin
Приём есть такой для убирания многочисленных параметов методов — параметры складываются в какую-то полиморфную структуру типа
map< string , variant > и передаются списком
Я так понимаю, это хорошо работает, когда ты знаешь весь возможный набор типов. Иначе их в variant не запихнёшь
источник

IZ

Ilia Zviagin in pro.cxx
Илья Шишков
Я так понимаю, это хорошо работает, когда ты знаешь весь возможный набор типов. Иначе их в variant не запихнёшь
variant тут как идея только.
источник

m

magras in pro.cxx
Илья Шишков
Привет! Есть два класса с похожими шаблонными методами.
struct A {
 template<typename... Args>
 void Do(int x, string s, Args&& args...);
};

struct B {
 template <typename... Args>
 void Do(Args&& args...);
};


И есть функции, которые делают одно и то же, но внутри себя вызывают либо A::Do, либо B::Do. Из-за этого их приходится реализовывать дважды:

void DoSomething(char c, bool q, int x, string s, A& a);
void DoSomething(char c, bool q, B& b);


Хочется спрятать A и B за общим интерфейсом, чтобы не дулировать код функций DoSomething. Всё, что удалось придумать — это сделать DoSomething шаблонной и передавать туда некое подобие лямбды, которая дёргает либо A, либо B.

Но из-за этого пришлось код DoSomething перетащить из cpp-файла в заголовчный. А вот как сделать так, чтобы реализации остались в cpp-файле, пока придумать не удалось.

У вас идеи?
А зачем код шаблона помещать в хедер? Можно оставить в cpp и просто явно инстанцировать для A и B.
источник

T

Turunchuk in pro.cxx
Илья Шишков
Привет! Есть два класса с похожими шаблонными методами.
struct A {
 template<typename... Args>
 void Do(int x, string s, Args&& args...);
};

struct B {
 template <typename... Args>
 void Do(Args&& args...);
};


И есть функции, которые делают одно и то же, но внутри себя вызывают либо A::Do, либо B::Do. Из-за этого их приходится реализовывать дважды:

void DoSomething(char c, bool q, int x, string s, A& a);
void DoSomething(char c, bool q, B& b);


Хочется спрятать A и B за общим интерфейсом, чтобы не дулировать код функций DoSomething. Всё, что удалось придумать — это сделать DoSomething шаблонной и передавать туда некое подобие лямбды, которая дёргает либо A, либо B.

Но из-за этого пришлось код DoSomething перетащить из cpp-файла в заголовчный. А вот как сделать так, чтобы реализации остались в cpp-файле, пока придумать не удалось.

У вас идеи?
Сигнатуру метода Do  в структуре A сделать,  как в В. Пак аргументов кидать в tuple,  и зная что первые два аргумента int и string, откусывать их методом get.  Не?
источник

S

SupaproBot in pro.cxx
Переслано от Aleksei Budyakov
В чем преимущества и недостатки imgui в сравнении с qt /wx ?
Меня немного отпугивает разнообразие бэкендов, каждый со своим апи
источник

IZ

Ilia Zviagin in pro.cxx
Переслано от Anatoly Shirokov
Я qt/wx знаю, imgui нет. Преимущества qt/wx очевидны
источник