2017-01-11 3 views
1

Я хочу, чтобы реализовать шаблон класса, который:станд :: кортеж станд :: shared_ptr параметра шаблона пакета

  1. ведет себя как функция
  2. это входные и выходные переменные все совместно.
  3. относительно прост в использовании.

В результате, я строю следующее:

// all input/output variable's base class 
class basic_logic_parameter; 

// input/output variable, has theire value and iterators to functions that reference to this variable 
template <typename FuncIterator, typename ValueType> 
class logic_parameter 
    :public basic_logic_parameter 
{ 
private: 
    std::list<FuncIterator> _refedFuncs; 
    ValueType _val; 
public: 

}; 

// all `function`'s base class 
class basic_logic_function 
{ 
public: 
    virtual ~basic_logic_function() = 0; 
}; 

// the function, has input/output variable 
template <typename FuncIterator, typename R, typename... Args> 
class logic_function_base 
    :public basic_logic_function 
{ 
private: 
    std::shared_ptr<logic_parameter<FuncIterator, R>> _ret; 
    std::tuple<std::shared_ptr<logic_parameter<FuncIterator, Args>>...> _args; 
public: 
    template <std::size_t N> 
    decltype(auto) arg() 
    { 
     return std::get<N>(_args); 
    } 

    template <std::size_t N> 
    struct arg_type 
    { 
     typedef std::tuple_element_t<N> type; 
    }; 

    template <std::size_t N> 
    using arg_type_t = arg_type<N>::type; 

    decltype(auto) ret() 
    { 
     return _ret; 
    } 
}; 

Я хотел бы использовать, поскольку они, как:

// drawing need color and a pen 
    struct Color 
    { 
    }; 

    struct Pen 
    { 
    }; 

    struct Iter 
    { 
    }; 

    class Drawer 
     :public logic_function_base<Iter, void(Color, Pen)> 
    { 
    public: 
     void draw() 
     { 
      arg_type_t<0> pColor; // wrong 
     } 
    } 

Мой компилятор не может передать этот код через, почему? Я просто хочу преобразовать параметр шаблона пакета в std::tuple of std::shared_ptr of them. , например:

Учитывая struct A, int, struct C, я хочу иметь:

std::tuple< 
    std::shared_ptr<logic_parameter<A>>, 
    std::shared_ptr<logic_parameter<int>>, 
    std::shared_ptr<logic_parameter<C>>, 
> 
+0

Там очевидные ошибки в коде (отсутствующий 'кортеж 'для' std :: tuple_element_t' или отсутствует 'typename'), являются ли эти ошибки копирования/вставки? – Holt

+1

'R (Args ...)' не магически расширен в 'typename R, typename ... Args' самостоятельно, perpahs [использовать частичную специализацию и исправить пару ошибок] (http: //coliru.stacked -crooked.com/a/e9c5cd84502ef962) –

+0

@Holt это ошибка ввода :) – ChungkingExpress

ответ

2

Проблема (как только небольшие ошибки исправляются) является то, что вы инстанцируете:

logic_function_base<Iter, void(Color, Pen)> 

... это означает, что FuncIterator является Iter и R является void(Color, Pen), так Args пуст <>, так decltype(_args) является пустым std::tuple<>, и ваш код не может получить тип 0-го элемента пустого кортежа, что является законным.

То, что вы хотите, частичная специализация logic_function_base:

template <typename F, typename T> 
class logic_function_base; 


template <typename FuncIterator, typename R, typename... Args> 
class logic_function_base<FuncIterator, R(Args...)>: public basic_logic_function { 

}; 

Небольшие ошибки в текущем коде:

template <std::size_t N> 
struct arg_type 
{ 
    typedef std::tuple_element_t<N, decltype(_args)> type; // Missing the tuple type 
}; 

template <std::size_t N> 
using arg_type_t = typename arg_type<N>::type; // Missing a typename 
+0

IT помогает! Спасибо!;) – ChungkingExpress

0

Это не может ответить на весь ваш вопрос, но вы можете использовать следующую черту, чтобы обернуть типы элементов кортежа.

template <typename T> struct wrap; 
template <typename... T> 
struct wrap<std::tuple<T...>> { 
    using type = std::tuple<std::shared_ptr<logic_parameter<T>>...>; 
} 
template <typename T> 
using wrap_t = typename wrap<T>::type; 

Вы можете использовать его как это:

std::tuple<int,double,char> t1; 
wrap_t<decltype(t)> t2; 

Тип t2 является std::tuple<std::shared_ptr<logic_parameter<int>>,std::shared_ptr<logic_parameter<double>>,std::shared_ptr<logic_parameter<char>>>.

+0

Спасибо за ваш ответ – ChungkingExpress

+0

@ChungkingExpress Обычно в stackoverflow обычно повышается, а не благодарит в комментариях. Но, пожалуйста. Приветствия. – SU3

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