Я бы хотел направить вызов функтора и скопировать этот функтор только тогда, когда это абсолютно необходимо. Вот моя общая функция обертка и функтор:Вперед функторы с минимальным копированием
template <typename F>
void wrapper (F func)
{
func();
}
struct Functor
{
Functor() {}
void operator()() { /* do some work */ }
};
Я могу назвать обертка с
- ссылка Rvalue: обертка (Functor());
- lvalue reference: Functor f; Обертка (е);
- const lvalue reference: const Functor f; Обертка (е);
- const rvalue reference: const Functor make_functor(); wrapper (make_functor());
Я хочу скопировать аргумент обертки только тогда, когда были переданы ссылки на const. Поэтому я пришел к такой реализации обертки:
using safe_mutual_handler_type =
typename std::conditional<
std::is_reference<F>::value
, typename std::conditional<
std::is_const<typename std::remove_reference<F>::type>::value
, typename std::remove_const<typename std::remove_reference<F>::type>::type
, F&
>::type
, F&
>::type;
template <typename F>
void wrapper (F&& func)
{
safe_mutual_handler_type<F> tmp = func;
tmp();
}
Не очень хорошие и промаха (не очень типичные) Const-Rvalue ссылок случай, но в основном, делаю свою работу.
Но я также может иметь Functor с сопзЬ оператором()
struct Functor {
Functor() {}
void operator()() const {}
};
И в этом случае мне не нужно копировать ARG обертки вообще.
Вопрос в том, как я могу проверить упаковку, если Функтор имеет оператор скобки в скобках? Другой вопрос в том, может ли обертка реализовать более умным и компактным способом без огромного количества строк типа typedefs? (на самом деле я беспокоюсь не о размере кода, а о читаемости кода).