Вывод конкатенации вариационных шаблонов

Таким образом, вопрос прост: должен ли компилятор выводить конкатенацию шаблонов в соответствии со стандартом?

Пример:

template<typename... RUN_TIME, typename T, typename... CONSTRUCTION_TIME>
Runnable<T, RUN_TIME...>* makeRunnable(T (*FunctionType)(CONSTRUCTION_TIME..., RUN_TIME...), CONSTRUCTION_TIME... ct_args)
{
...
}

int print_function(char arg1, int arg2, const char* arg3);

makeRunnable<const char*>(print_function, 'C', -3);

Если компиляция сможет понять, что функция print_function все в порядке, учитывая аргументы и явный шаблон?

Узнать больше; Предыдущий вопрос

1

Решение

Помимо вопроса о том, что стандарт говорит о том, какие компиляторы должен быть в состоянии сделать, вот некоторые TMP, чтобы сделать его компиляцией на GCC:

/** PackDiff:
*  Template Metafunction to deduce the difference of two parameter packs.
*  To distinguish two packs we have to brace them in two tuples
*/
template <class Tup1, class Tup2> struct PackDiff;

/** Basic algorithm: (T, X1...) - (T, X2...) = (X1...) - (X2...) */
template <class T, class... Pack1, class... Pack2>
struct PackDiff<std::tuple<T, Pack1...>, std::tuple<T, Pack2...>>
: PackDiff<std::tuple<Pack1...>, std::tuple<Pack2...>> {};

/** End of recursion: (X1...) - () = (X1...) */
template <class... Pack1>
struct PackDiff<std::tuple<Pack1...>, std::tuple<>>
{
typedef std::tuple<Pack1...> type;
};

/** Mismatch: (T, X1...) - (U, X2...) is undefined */
template <class T1, class... Pack1, class T2, class... Pack2>
struct PackDiff<std::tuple<T1, Pack1...>, std::tuple<T2, Pack2...>>
{ typedef struct PACK_MISMATCH {} type; };

/** Rest: () - (X2...) is undefined */
template <class... Pack2>
struct PackDiff<std::tuple<>, std::tuple<Pack2...>>
{ typedef struct LEFT_PACK_TOO_SHORT{} type; };//make Runnable Type of T and a diff tuple:
template <class T, class Tup1> struct MakeRunnableType;

template <class T, class... Pack>
struct MakeRunnableType<T, std::tuple<Pack...>>
{ typedef Runnable<T, Pack...> type; };template<typename... AllArgs, typename T, typename... SomeArgs>
auto makeRunnable(T (*FunctionType)(AllArgs...), SomeArgs... ct_args)
-> typename MakeRunnableType<T,
typename PackDiff<std::tuple<AllArgs...>,
std::tuple<SomeArgs...>
>::type
>::type*
{
typedef typename PackDiff<std::tuple<AllArgs...>,
std::tuple<SomeArgs...>
>::type PackDiff_t;
typedef typename MakeRunnableType<T, PackDiff_t>::type ReturnType;
return new ReturnType();
}

Я знаю. Не выглядит очень красиво. Но работает на GCC.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]