2014-12-03 4 views
1

Я могу создать класс шаблона, который хранит некоторые значения в свойстве и позвольте мне позже вызвать метод, вызывающий функцию с этим аргументом. Например:variadic template class, чтобы сделать отложенный вызов функции вариационного шаблона

template <typename U> void g(U u) { cout << u << endl; } 
template <typename U> class C { 
public: 
     U u; 
     C(U u) { this->u = u; } 
     void m() { g(u); } 
}; 

int main() { 
     C<double> c(5.5); 
     c.m(); 
} 

Но как сделать то же самое с вариативными шаблонами? Я хотел бы написать что-то вроде:

template <typename ... T> void f(T... a) { cout << "generik" << endl; } 

template <typename ... T> class B { 
    public: 
     T... arg; 
     B(T... arg) { 
      this->arg = arg; 
     } 
     void m() { f(arg); } 
}; 

int main() { 
    B<int,double> b(1,1.1); 
    b.m(); 
} 

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

Я могу выполнить сопоставление шаблонов для некоторых параметров списка, а затем вызвать функцию, если задано заданное число параметров, но я хочу сделать это в общем виде. Есть ли элегантный способ сделать это?

+0

Использование 'станд :: tuple' –

+0

Ваш первый пример не в состоянии совершенствовать вперед, а также. Вы собираетесь называться 'm' более одного раза? Может быть, только перегрузка '&&' должна быть идеальной вперед ... – Yakk

+0

Это было не главное, но спасибо. –

ответ

1

http://ideone.com/OPl7Rz

#include <iostream> 
#include <functional> 

using namespace std; 

template<typename... T> 
void f(T... a) 
{ 
    std::initializer_list<int> {(std::cout<<a<<" ", 0)...}; 
} 

template<typename... T> 
class Defer 
{ 
    private: 
     std::function<void()> func; 

    public: 
     Defer(T... a) : func(std::bind(f<T...>, a...)) {} 
     void call() {func();} 
}; 



int main() 
{ 
    Defer<int, float, int, const char*> d(1, 1.1, 2, "Hey"); 
    d.call(); 
    return 0; 
} 
+0

Спасибо @Brandon, это соответствует моим потребностям и его совершенно элегантным! Не знал, почему я не думал о привязке (нужно больше копать на вариативных шаблонах и стандартном lib). –

2

Вы можете использовать что-то вроде следующего:

template <typename... Ts> class B 
{ 
public: 
    std::tuple<Ts...> t; 
    B(Ts... args) 
     : t(args...) 
    { 
    } 
    void m() { call_f(std::index_sequence_for<Ts>()); } 

private: 
    template <std::size_t ... Is> 
    void call_f(std::index_sequence<Is...>) 
    { 
     f(std::get<Is>(t)...); 
    } 
}; 

Обратите внимание, что std::index_sequence_for (std::make_index_sequence) и std::index_sequence являются C++ 14, но могут быть написаны на C++ 11.

Live example.

+2

Можете упомянуть, что делает 'make_index_sequence'. Или я думаю, они могут это сделать. 'index_sequence_for ' может быть лучше, чем 'make_index_sequence '. – Yakk

+0

Спасибо, ребята, за ваши хорошие ответы, но я предпочитаю @ Ответ Брэндона: он полностью совместим с C++ 11 и немного более сложным. Даже если ваши магазины хранят данные, а не вызов функции ... Я колебался ... –

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

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