Пример шаблона вариации VS2010 C ++ - PullRequest
8 голосов
/ 21 января 2011

У меня есть шаблон класса, и я не могу понять, как выполнить реализацию стиля Variadic Template.

Вот "код" того, что я ищу:

template<typename _Classname, typename... Args>
class CFunctorStartExT 
{
  friend class CXXFactory;
protected:
  template<typename U>
  CFunctorStartExT(typename U& _functor, Args&... args) :
    m_Functor(_functor),
    m_args(args)
  {
  }
  virtual bool ProcessLoop(CSomeClass* pThread)
  {
    return m_Functor(pThread, m_args);
  }

protected:
  _Classname& m_Functor;
  Args... m_args;
};

Очевидно, что это не скомпилируется :). Идея состоит в том, чтобы создать класс, который может хранить передаваемые значения (если они есть .., он может просто иметь определенное _Classname / U) в конструкторе, чтобы их можно было извлечь позже для передачи в m_Functor в другой функции.

Во-первых: можно ли сделать шаблон Variadic в VS2010? Я получаю проблемы компиляции только с объявлением шаблона error C2143: syntax error : missing ',' before '...' из строки template<typename _Classname, typename... Args>

Во-вторых, что я пытаюсь сделать? Спасибо!

Ответы [ 3 ]

26 голосов
/ 22 января 2011

Visual C ++ 2010 не поддерживает шаблоны переменных.

3 голосов
/ 22 января 2011

Я верю, что следующее сделает то, что вы хотите.Сначала вам понадобится утилита:

// make_tuple_indices

template <size_t...> struct tuple_indices {};

template <size_t _Sp, class _IntTuple, size_t _Ep>
struct make_indices_imp;

template <size_t _Sp, size_t ..._Indices, size_t _Ep>
struct make_indices_imp<_Sp, tuple_indices<_Indices...>, _Ep>
{
    typedef typename make_indices_imp<_Sp+1, tuple_indices<_Indices..., _Sp>, _Ep>::type type;
};

template <size_t _Ep, size_t ..._Indices>
struct make_indices_imp<_Ep, tuple_indices<_Indices...>, _Ep>
{
    typedef tuple_indices<_Indices...> type;
};

template <size_t _Ep, size_t _Sp = 0>
struct make_tuple_indices
{
    static_assert(_Sp <= _Ep, "make_tuple_indices input error");
    typedef typename make_indices_imp<_Sp, tuple_indices<>, _Ep>::type type;
};

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

template<typename _Classname, typename... Args>
class CFunctorStartExT 
{
  friend class CXXFactory;
protected:
  template<typename U>
  CFunctorStartExT(U& _functor, Args&... args) :
    m_Functor(_functor),
    m_args(args...)
  {
  }

  virtual bool ProcessLoop(CSomeClass* pThread)
  {
    return ProcessLoop(pThread,
                       typename make_tuple_indices<sizeof...(Args)>::type());
  }

protected:
  _Classname& m_Functor;
  std::tuple<Args...> m_args;

private:
    template <std::size_t ...Indx>
    bool ProcessLoop(CSomeClass* pThread, tuple_indices<Indx...>)
    {
        return m_Functor(pThread, std::get<Indx>(m_args)...);
    }
};

Что касается поддержки шаблонов VS2010: у меня нетидея.

0 голосов
/ 22 января 2011

Шаблоны Variadic - это патч на ключе от взлома - вам это не понравится.Способ сделать это (вне головы) - использовать специализацию шаблонов вместе с наследованием.Что-то в этом роде:

template<typename Classname, typename... Args>
class CFunctorStartExT;

template<typename Classname, typename Arg0, typename... Args>
class CFunctorStartExT : private CFunctorStartExT<Classname, Args...> {
protected:
  Arg0 m_arg;
};

template<typename Classname>
class CFunctorStartExT {
protected:
  Classname &m_Functor;
};

Я никогда раньше этого не делал и не проверял, но это общая идея.Вы могли бы взглянуть на std::tuple реализацию чего-то, что действительно работает.

...