Как развернуть кортеж в аргументы функции шаблона переменной?

Я уже использую следующий метод в моем проекте:

func dateFormat(_ originalDate: String) -> String{
     let dateFormatter = DateFormatter()
     dateFormatter.dateFormat = "yyyy-MM-dd"
     dateFormatter.locale = Locale(identifier: "en_US_POSIX")
     let date = dateFormatter.date(from: originalDate)
     dateFormatter.dateFormat = "MMMM dd, yyyy"
     let valueDate = dateFormatter.string(from: date!)
     return valueDate
}

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

dateFormat("2019-03-22") // March 22, 2019
127
задан Xeo 4 February 2012 в 14:41
поделиться

2 ответа

Новости не выглядят хорошими.

Перечитав по просто выпущенному черновому стандарту, я не вижу встроенное решение этого, которое действительно кажется нечетным.

Лучшее место, чтобы спросить о таких вещах (если Вы уже не имеете) является comp.lang.c ++. модерируемый, потому что некоторые люди, вовлеченные в составление стандартного сообщения там регулярно.

Если Вы проверяете этот поток, у кого-то есть тот же вопрос (возможно, это - Вы, в этом случае Вы собираетесь найти этот целый ответ небольшим срывом!), и несколько ужасных торцом реализаций предлагаются.

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

Обновление: ссылка выше не работает - пытаются вставить это:

http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/750fa3815cdaac45/d8dc09e34bbb9661?lnk=gst&q=tuple+variadic#d8dc09e34bbb9661

1
ответ дан 24 November 2019 в 00:47
поделиться

Вот мой код, если кому-то интересно

В основном во время компиляции компилятор рекурсивно разворачивает все аргументы в различных включающих вызовах функций -> вызовов -> вызовов ... -> вызывает <0>, который является последним, и компилятор оптимизирует различные промежуточные вызовы функций, чтобы оставить только последний, который является эквивалентом func (arg1, arg2, arg3, ...)

Предусмотрены 2 версии, одна для функции, вызываемой для объекта, а другая для статической функции.

#include <tr1/tuple>

/**
 * Object Function Tuple Argument Unpacking
 *
 * This recursive template unpacks the tuple parameters into
 * variadic template arguments until we reach the count of 0 where the function
 * is called with the correct parameters
 *
 * @tparam N Number of tuple arguments to unroll
 *
 * @ingroup g_util_tuple
 */
template < uint N >
struct apply_obj_func
{
  template < typename T, typename... ArgsF, typename... ArgsT, typename... Args >
  static void applyTuple( T* pObj,
                          void (T::*f)( ArgsF... ),
                          const std::tr1::tuple<ArgsT...>& t,
                          Args... args )
  {
    apply_obj_func<N-1>::applyTuple( pObj, f, t, std::tr1::get<N-1>( t ), args... );
  }
};

//-----------------------------------------------------------------------------

/**
 * Object Function Tuple Argument Unpacking End Point
 *
 * This recursive template unpacks the tuple parameters into
 * variadic template arguments until we reach the count of 0 where the function
 * is called with the correct parameters
 *
 * @ingroup g_util_tuple
 */
template <>
struct apply_obj_func<0>
{
  template < typename T, typename... ArgsF, typename... ArgsT, typename... Args >
  static void applyTuple( T* pObj,
                          void (T::*f)( ArgsF... ),
                          const std::tr1::tuple<ArgsT...>& /* t */,
                          Args... args )
  {
    (pObj->*f)( args... );
  }
};

//-----------------------------------------------------------------------------

/**
 * Object Function Call Forwarding Using Tuple Pack Parameters
 */
// Actual apply function
template < typename T, typename... ArgsF, typename... ArgsT >
void applyTuple( T* pObj,
                 void (T::*f)( ArgsF... ),
                 std::tr1::tuple<ArgsT...> const& t )
{
   apply_obj_func<sizeof...(ArgsT)>::applyTuple( pObj, f, t );
}

//-----------------------------------------------------------------------------

/**
 * Static Function Tuple Argument Unpacking
 *
 * This recursive template unpacks the tuple parameters into
 * variadic template arguments until we reach the count of 0 where the function
 * is called with the correct parameters
 *
 * @tparam N Number of tuple arguments to unroll
 *
 * @ingroup g_util_tuple
 */
template < uint N >
struct apply_func
{
  template < typename... ArgsF, typename... ArgsT, typename... Args >
  static void applyTuple( void (*f)( ArgsF... ),
                          const std::tr1::tuple<ArgsT...>& t,
                          Args... args )
  {
    apply_func<N-1>::applyTuple( f, t, std::tr1::get<N-1>( t ), args... );
  }
};

//-----------------------------------------------------------------------------

/**
 * Static Function Tuple Argument Unpacking End Point
 *
 * This recursive template unpacks the tuple parameters into
 * variadic template arguments until we reach the count of 0 where the function
 * is called with the correct parameters
 *
 * @ingroup g_util_tuple
 */
template <>
struct apply_func<0>
{
  template < typename... ArgsF, typename... ArgsT, typename... Args >
  static void applyTuple( void (*f)( ArgsF... ),
                          const std::tr1::tuple<ArgsT...>& /* t */,
                          Args... args )
  {
    f( args... );
  }
};

//-----------------------------------------------------------------------------

/**
 * Static Function Call Forwarding Using Tuple Pack Parameters
 */
// Actual apply function
template < typename... ArgsF, typename... ArgsT >
void applyTuple( void (*f)(ArgsF...),
                 std::tr1::tuple<ArgsT...> const& t )
{
   apply_func<sizeof...(ArgsT)>::applyTuple( f, t );
}

// ***************************************
// Usage
// ***************************************

template < typename T, typename... Args >
class Message : public IMessage
{

  typedef void (T::*F)( Args... args );

public:

  Message( const std::string& name,
           T& obj,
           F pFunc,
           Args... args );

private:

  virtual void doDispatch( );

  T*  pObj_;
  F   pFunc_;
  std::tr1::tuple<Args...> args_;
};

//-----------------------------------------------------------------------------

template < typename T, typename... Args >
Message<T, Args...>::Message( const std::string& name,
                              T& obj,
                              F pFunc,
                              Args... args )
: IMessage( name ),
  pObj_( &obj ),
  pFunc_( pFunc ),
  args_( std::forward<Args>(args)... )
{

}

//-----------------------------------------------------------------------------

template < typename T, typename... Args >
void Message<T, Args...>::doDispatch( )
{
  try
  {
    applyTuple( pObj_, pFunc_, args_ );
  }
  catch ( std::exception& e )
  {

  }
}
45
ответ дан 24 November 2019 в 00:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: