2016-08-30 1 views
1

Я немного рассол, следуя моему previous question и используя код, похожий на тот, который я posted here.получение типа шаблона из лямбда-авто

  1. Я использую VARIADIC шаблонную функцию, которая принимает VARIADIC объекты
  2. Он упаковывает их в кортеж
  3. итерацию их с помощью visitor идиомы
  4. Становится персональным для каждого объекта обратного вызова

Вместо этого первоначального приведенного ниже примера:

template <typename... Args> 
void make_classes(Args... args) 
{ 
    auto t = std::tuple<Args...>(args...); 
    unsigned int size = std::tuple_size<decltype(t)>::value; 
    auto execute = [](auto & obj){ obj.operator()(); }; 

    for (int i = 0; i < size; i++) { 
     visit_at(t, i, execute); 
    } 
} 

Я пытаюсь понять, как я могу вывести тип шаблона из auto лямбды, так что я могу связать его:

template <typename... Args> 
void make_classes(Args... args) 
{ 
    auto t = std::tuple<Args...>(args...); 
    unsigned int size = std::tuple_size<decltype(t)>::value; 
    auto execute = [](auto & obj){ 
     // obtain type of obj as T? 
     auto callback = std::bind(&T::deserialise, obj, std::placeholders::_1); 
     // do something else here using this callback. 
    }; 

    for (int i = 0; i < size; i++) { 
     visit_at(t, i, execute); 
    } 
} 

Там подвох: объекты параметров не являются копируемыми (хотя я мог бы изменить что), но я хотел бы знать, может ли/как это сделать, выведя тип шаблона, упакованный в кортеж, полученный посетителем.

Если я не могу вывести тип внутри лямбда, может я как-то магазин его в кортеж (например,:. Тип & объекта), чтобы потом извлечь его?

+0

вам не нужно 'decltype ли (авто) '? – NathanOliver

+0

@NathanOliver Я не знаю, как это будет работать? –

+0

@NathanOliver кажется, что вы что-то делаете, используя 'decltype (obj' возвращает' error: type 'decltype (obj)' не может использоваться до '::', потому что у него нет членов 'с правильным типом, напечатанным в ошибка –

ответ

6

Просто используйте другой лямбда:

auto callback = [&obj](auto& x){ 
    obj.deserialise(x); 
}; 

std::bind редко бывает полезным. (Если вы действительно хотите скопировать obj, вы можете оставить ведущую &.)


Кроме того, вы на самом деле не нужен кортеж ...

template <class F, class... Args> 
void for_each_arg(F&& f, Args&&... args) { 
    using swallow = int[]; 
    (void)swallow{0, 
     (void(f(std::forward<Args>(args))), 0)... 
    }; 
} 

template <typename... Args> 
void make_classes(Args... args) 
{ 
    for_each_arg([](auto& obj){ 
     auto callback = [&obj](auto& x) { obj.deserialise(x); }; 
     // do something with callback 
    }, args...); 
} 
+0

wow большое спасибо, это намного проще, потребуется некоторое время для переваривания. –

+1

@ Ælex См. [ TC)] (http://stackoverflow.com/a/30563282/2069064) для хорошего объяснения. – Barry

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