Вот проблема, с которой я столкнулся во время игры с вариативными шаблонами. У меня есть некоторый код, который использует специализацию для подсчета «интересных» типов в параметрах пакета, как так:специализация вариативных шаблонов с шаблонами классов
template<typename... _Pp>
struct count;
template<>
struct count<>
{
static const int value = 0;
};
// ignore uninteresting types
template<typename _First, typename... _Rest>
struct count<_First, _Rest...>
{
static const int value = count<_Rest...>::value;
};
// add 1 for a pointer
template<typename _First, typename... _Rest>
struct count<_First*, _Rest...>
{
static const int value = 1 + count<_Rest...>::value;
};
// add 1 for a reference
template<typename _First, typename... _Rest>
struct count<_First&, _Rest...>
{
static const int value = 1 + count<_Rest...>::value;
};
// add 1 for an int
template<typename... _Rest>
struct count<int, _Rest...>
{
static const int value = 1 + count<_Rest...>::value;
};
Этот код работает отлично, но я бег в проблемы, если я хочу использовать тот же подход для подсчета шаблонов классов:
// add 1 for a vector
template<typename... _Rest>
struct count<vector, _Rest...>
{
static const int value = 1 + count<_Rest...>::value;
};
выше код не компилировать, ошибка «ожидается тип, получил„вектор“» на строку, начинающуюся с «подсчета STRUCT». Я также не в состоянии что-нибудь попроще, все шаблоны классов, принимающие один аргумент:
// add 1 for a class template with 1 type parameter
template<template<typename> class _First, typename... _Rest>
struct count<_First, _Rest...>
{
static const int value = 1 + count<_Rest...>::value;
}
Этот код также не компилировать, жалуясь на «ожидается типа, получил" _First»в очередной раз на линии, начиная с "struct count". Кто-нибудь знает способ достижения этой цели с использованием этого подхода (т. Е. Некоторые изменения, которые я могу внести в одну или обе специализации, которые заставят их скомпилировать и выполнить требуемый расчет во время компиляции)?
EDIT: Я хочу, чтобы пакет параметров для вектора быть несвязанным, похожий на следующий код для простого контейнера оберткой с переменным числом параметров шаблона шаблона, который также специализируется на станд :: вектор:
// pass a container as a parameter using variadic template-template
parameter
template<typename _Tp, template<typename...> class _C>
struct success
{
// not specialized for any container
static const bool is_specialized = false;
// data member of container type
_C<_Tp> c_;
};
// partial specialization of above for std::vector
template<typename _Tp>
struct success<_Tp, std::vector>
{
// specialized for vector
static const bool is_specialized = true;
// again, data member of container type
std::vector<_Tp> c_;
};
EDIT Похоже, что окончательный ответ заключается в том, что то, что я хочу сделать, не может быть выполнено, но я нашел способ перефразировать проблему, чтобы я мог ее решить. Огромное спасибо тем, кто помогал.
Претензия «но вы не можете смешивать шаблоны классов и простые типы имен», по-видимому, является ключевой проблемой здесь; Я немного посмотрел на рабочий проект N3797, но не могу понять, что такое правила, можете ли вы указать мне больше информации об этом ограничении? –
@BDatRivenhill - Извините: я исправляю себя: вы не можете смешивать шаблоны классов и простые имена в одном и том же параметре шаблона * pack *. Obviouly вы можете смешать создать класс templare, который ожидает одиночные имена типов и один шаблон. Но когда вы создаете пакет параметров, существуют разные производственные правила (если я не ошибаюсь), а пакет параметров может принимать только типы имен ('typename ... Ts') или шаблоны (' template class ... Cs') , –
max66
@BDatRivenhill - Укажите мне больше информации об этом ограничении? Я полагаю, что это сомнение вызывает другой вопрос и, извините, но я не очень хорошо разбираюсь в стандарте. Я читаю N3797, который вы назвали, но для меня это слишком сложно. Я полагаю, что могут быть релевантными различные правила производства (14.1) и правило сопоставления в 14.3: (продолжение) – max66