2016-04-11 4 views
0

Я свяжусь с тем, чтобы написать простой шаблон шаблонов универсальных указателей, который позволяет программисту применять произвольное количество оберток до и после вызова некоторой функции FUNC() , например. Если требовалось запустить таймер, заблокировать, log_start, FUNC(), log_end, разблокировать, остановить таймерОбобщение функций общего C++

Тогда я хотел бы иметь возможность написать что-то простое, где программист поставил 3 типа и функцию для шаблона и пусть компилятор сделает все остальное. я получаю чувство, что это может быть сделано с помощью VARIADIC шаблоны аналогично тому, как списки типов работали в сочетании с перегрузкой оператора ->

т.е.

class timer {}; // ctor start timer, dtor stop timer 
class locker{}; // ctor lock, dtor unlock 
class logger{}; // ctor lock, dtor unlock 

Тогда код, такой как

template <typename ...base_class_list> 
class aggregate : public base_class_list... {}; 
using pre_conditions = aggregate<logger, locker, trans>; 

class gadget 
{ 
    auto do_something() -> void; 
}; // gadget 

Наконец (часть, которую я хотел бы написать, но не знаю, как склеить ее вместе

SMART_PTR<pre_conditions, gadget> g; 
g->do_something(); 

Я могу заставить его работать достаточно легко, используя подход, описанный Bjarne Stroustrup в разделе «Условные вызовы функций C++ Member», но задавался вопросом, было ли более общее и изящное решение.

+0

Просьба уточнить вашу конкретную проблему или добавить дополнительные сведения, чтобы точно указать, что вам нужно. Как это написано в настоящее время, трудно точно сказать, что вы просите. См. Страницу [Как спросить] (http://stackoverflow.com/help/how-to-ask), чтобы помочь прояснить этот вопрос. – Barry

+1

Этот вопрос ссылается на очень хороший пример Mixins, который, как мне кажется, связан с тем, что вы пытаетесь сделать: http://stackoverflow.com/questions/34193264/mixin-and-interface-implementation/34193545#34193545 –

+0

Я думаю, вы в [аспектно-ориентированное программирование] (https://en.wikipedia.org/wiki/Aspect-oriented_programming#cite_note-22), для которого было разработано несколько рамок и наборов инструментов около 2000 года и позже. Например. посмотрите [AspectC++] (https://en.wikipedia.org/wiki/AspectC%2B%2B) (я не использовал его, я просто нашел его по поисковому запросу). Насколько я знаю, идея возникла в ParkPlace. –

ответ

0

Самый простой способ заключается в оберточную только все operator():

template <typename T, typename ... Ts> 
struct magic 
{ 
    T obj; 

    template <typename ... Us> 
    decltype(auto) operator()(Us...args) 
    { 
     ordered_tuple<Ts...> t; // tuple doesn't guaranty order 
     obj(std::forward<Us>(args)...); 
    } 
}; 

Demo

Завернуть operator ->, это более сложно:

template <typename T, typename ... Ts> 
class wrapper 
{ 
    ordered_tuple<Ts...> t; // tuple doesn't guaranty order 
    T* obj; 
public: 
    wrapper(T* obj) : obj(obj) {} 

    T* operator ->() 
    { 
     return obj; 
    } 
}; 

template <typename T, typename ... Ts> 
class magic 
{ 
    T obj; 
public: 
    wrapper<T, Ts...> operator ->() 
    { 
     return {&obj}; 
    } 
}; 

Demo

Handling 10 и нестандартный конструктор. (и найти лучшее имя).

+0

Отлично, это именно то, что я искал. – PMcK

+0

И теперь его записано в блоге https://patmckblog.wordpress.com/2016/04/14/a-hidden-gem-overloading-operator/ – PMcK

+0

@PMcK: Я бы добавил комментарий о различии между 'std: : tuple' и ваш класс 'aggregate' (который может быть не совокупным btw) (поэтому я назвал его' ordered_tuple'). – Jarod42

 Смежные вопросы

  • Нет связанных вопросов^_^