2016-05-06 2 views
2

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

Прямо сейчас, у меня есть это:

template<class T> 
struct TIsTemplated { enum { Value = 0 }; }; 

template<template<typename, typename...> class T, typename First, typename... Values> 
struct TIsTemplated<T<First, Values...>> { enum { Value = 1 }; }; 

Это хорошо работает для шаблонных типов, как

template<typename T> 
struct X { }; 

Это терпит неудачу, однако, как только есть тип, который имеет постоянные значения:

template<typename T, int i = 10> 
struct Y {}; 

Я узнал, что могу сделать такой тип:

template<int A, template<typename, int> class T, typename First> 
struct TIsTemplated<T<First,A>> { enum { Value = 1 }; }; 

Однако это работает только в том случае, если я знаю, что у меня будет тип, который принимает int. Я попытался обобщить это:

template<typename C> 
template<C A, template<typename, C> class T, typename First> 
struct TIsTemplated<T<First,A>> { enum { Value = 1 }; }; 

Но даже если это компилирует правильно, TIsTemplated еще ложна для типа Y. Есть ли способ достичь этого, не зная постоянный тип?

+0

Можете ли вы дать контекст Asto, почему вы думаете, что вам нужно сделать это? Это похоже на высказывание «независимо от его текущих свойств, мне нужно идентифицировать все кирпичи, произведенные в южной половине их соответствующего состояния». – Yakk

+1

Я создаю некоторые привязки из C++ на другой язык, и, хотя большинство типов могут использовать обобщенную реализацию, шаблонные типы должны иметь реализацию для каждого типа.Мне нужно как-то найти способ сказать компилятору C++ не использовать реализацию по умолчанию в этих случаях. Для контекста, проект https://github.com/proletariatgames/unreal.hx, и пока шаблоны работают в настоящее время, я пересматриваю, как они обрабатываются, поэтому мы можем генерировать меньше мусора кода клея – Waneck

+1

Зачем ему нужна реализация для Каждый тип? Если вы привязываете шаблон, это одно, но если вы привязываете тип, сгенерированный шаблоном, почему это подразумевает привязку каждого типа, который может быть сгенерирован указанным шаблоном? Тип, сгенерированный шаблоном, является деталью реализации. Во-вторых, существует ли конечный список таких шаблонов, которые нужно обернуть? Вы можете относительно легко обернуть данный шаблон (или шаблон шаблона) с помощью параметра hedroginous template «виды» в один, который принимает только типы, а затем решает проблему шаблона только для типа. – Yakk

ответ

1
template<class...>struct types{using type=types;}; 

- это набор типов.

template<class Scalar, class T> 
struct is_template_with_scalar : std::false_type {}; 

template<class Scalar, template<class,Scalar>class Z, class U, Scalar s> 
struct is_template_with_scalar<Scalar, Z<U,s>> : std::true_type {}; 

ли тест дана Scalar типа, делает тип T соответствует шаблону template<class, Scalar>.

Затем мы снискать его немного:

template<class Scalar> 
struct scalar_test { 
    template<class T> 
    using result=is_template_with_scalar<Scalar, T>; 
}; 

Это занимает кучу типов BOOL, и оценивает их логическое или:

template<class...Ts> 
struct or_types : std::false_type {}; 

template<class T0, class...Ts> 
struct or_types<T0, Ts...> : std::integral_constant<bool, T0{} || or_types<Ts...>{} > 
{}; 

passes_any принимает список типов, и мета- тест, который принимает тип. Она производит тест, который определяет, будет ли какой-либо из тестов передаются:

template<class List, template<class>class Test> 
struct passes_any {}; 

template<class...Ts, template<class>class Test> 
struct passes_any<types<Ts...>, Test> { 
    template<class U> 
    using result=or_types< typename Test<Ts>::template result<U>... >; 
}; 

Теперь мы начинаем с:

using scalars_supported = types<int, char, std::size_t, unsigned>; // etc 

И мы получаем тест:

template<class T> 
using is_scalar_template = 
    typename passes_any<scalars_supported,scalar_test>::template result<T>; 

, который по заданному тип T является правдивым типом, если это экземпляр шаблона с шаблоном <class, Scalar> для любого Scalar в списке scalars_supported.

live example

+0

Я не могу вас поблагодарить! Эта реализация потрясающая! – Waneck

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