Константность аргументов в функции
От: koenjihyakkei Россия  
Дата: 07.03.19 14:29
Оценка:
Привет!
Есть примерно такая функция(реальная больше):
void DoWork(Obj* obj, int num, void (*func)(Obj*))
{
    func(obj->GetChild());
}

Она будет вызываться как для константного obj, так и нет.
Так вот вопрос: можно ли это сделать без перегрузки функции? Не хочется дублировать код.

Спасибо.
Re: Константность аргументов в функции
От: kov_serg Россия  
Дата: 07.03.19 14:49
Оценка:
Здравствуйте, koenjihyakkei, Вы писали:

K>Есть примерно такая функция(реальная больше):

K>
K>void DoWork(Obj* obj, int num, void (*func)(Obj*))
K>{
K>    func(obj->GetChild());
K>}
K>

K>Она будет вызываться как для константного obj, так и нет.
K>Так вот вопрос: можно ли это сделать без перегрузки функции? Не хочется дублировать код.

Например так:
template<class Obj>
void DoWork(Obj* obj, int num, void (*func)(Obj*))
{
    func(obj->GetChild());
}
Re: Константность аргументов в функции
От: rg45 СССР  
Дата: 07.03.19 14:50
Оценка:
Здравствуйте, koenjihyakkei, Вы писали:

K>Привет!

K>Есть примерно такая функция(реальная больше):
K>
K>void DoWork(Obj* obj, int num, void (*func)(Obj*))
K>{
K>    func(obj->GetChild());
K>}
K>

K>Она будет вызываться как для константного obj, так и нет.
K>Так вот вопрос: можно ли это сделать без перегрузки функции? Не хочется дублировать код.


Шаблонный вариант не подойдет? Оно заодно даст возможность использовать функциональные объекты и лябмды:

https://ideone.com/dHJdbp

template <typename F>
void DoWork(Obj* obj, int num, F&& func)
{
    func(obj->GetChild());
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Константность аргументов в функции
От: koenjihyakkei Россия  
Дата: 07.03.19 14:56
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Например так:

_>
_>template<class Obj>
_>void DoWork(Obj* obj, int num, void (*func)(Obj*))
_>{
_>    func(obj->GetChild());
_>}
_>


Да как вариант рассматривал. Но Obj всегда будет одного типа, просто либо const либо нет, и выносить его в шаблон мне казалось излишним. Но скорее всего так и сделаю, просто подумал может есть другой способ.
Re[2]: Константность аргументов в функции
От: koenjihyakkei Россия  
Дата: 07.03.19 14:58
Оценка:
Здравствуйте, rg45, Вы писали:

R>Шаблонный вариант не подойдет? Оно заодно даст возможность использовать функциональные объекты и лябмды:


R>https://ideone.com/dHJdbp


R>
R>template <typename F>
R>void DoWork(Obj* obj, int num, F&& func)
R>{
R>    func(obj->GetChild());
R>}
R>


Такой вариант тоже рассматривал, но тут не нравится, что сигнатура фнукции не видна.
Кстати а в плане перфоманса есть отличие в передаче указателя на функцию и использования шаблонной? С учетом того, что туда почти всегда будет лямбда передаваться.
Re[3]: Константность аргументов в функции
От: rg45 СССР  
Дата: 07.03.19 15:15
Оценка:
Здравствуйте, koenjihyakkei, Вы писали:

K>Такой вариант тоже рассматривал, но тут не нравится, что сигнатура фнукции не видна.


Сигнатуру функции можно зафиксировать при помощи SFINAE.

K>Кстати а в плане перфоманса есть отличие в передаче указателя на функцию и использования шаблонной?


Если оставить за скобками возможности оптимизации, то использование функционального объекта предпочтительнее, поскольку использование указателя на функцию — это дополнительная косвенность и адрес вызова вычисляется во время выполнения, а не во время компиляции.

K>С учетом того, что туда почти всегда будет лямбда передаваться.


Принимая указатель на функцию, ты сможешь передавать только простейшие лямбды, не использующие захват контекста. Таким образом, польза от лябмд сильно теряется. И вообще, указатели на функции для С++ противоестественны, ИМХО.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 07.03.2019 15:39 rg45 . Предыдущая версия . Еще …
Отредактировано 07.03.2019 15:38 rg45 . Предыдущая версия .
Re[3]: Константность аргументов в функции
От: kov_serg Россия  
Дата: 07.03.19 15:58
Оценка:
Здравствуйте, koenjihyakkei, Вы писали:

K>Здравствуйте, kov_serg, Вы писали:


_>>Например так:

_>>
_>>template<class Obj>
_>>void DoWork(Obj* obj, int num, void (*func)(Obj*))
_>>{
_>>    func(obj->GetChild());
_>>}
_>>


K>Да как вариант рассматривал. Но Obj всегда будет одного типа, просто либо const либо нет, и выносить его в шаблон мне казалось излишним. Но скорее всего так и сделаю, просто подумал может есть другой способ.

Просто может быть не один GetChild
struct Obj {
  Obj* GetChild();
  const Obj* GetChild() const;
...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.