Я пытаюсь использовать класс шаблона в качестве параметра шаблона шаблона с другим параметром шаблона. Как это звучит, это довольно сложно/запутанно, и я не могу понять, как исправить ошибку компилятора.
То, что я написал, похоже на «std::find_if», но работает для «std::tuple». Как показано в приведенном ниже коде, он работает, когда я указываю тип для is_same_type_tt, но когда я пытаюсь использовать параметр шаблона с is_same_type_tt, компилятор жалуется:
main.cpp:75:13: error: type/value mismatch at argument 2 in template parameter list for 'template<class TupleType, template<class> class Action> struct tuple_find_if_tt'
>::value;
^
Исходный код выглядит следующим образом:
template< typename TypeLookingFor >
struct is_same_type_tt
{
typedef TypeLookingFor type_looking_for;
template< typename TypeCompareTo >
struct type_tt : is_same< type_looking_for, TypeCompareTo >
{};
};
// base for the recusion
template<
typename TupleType
, size_t Index
, template< typename > class Action >
struct tuple_find_if_recur_tt;
// last in the recursion
template<
typename TupleLast
, size_t Index
, template< typename > class Action >
struct tuple_find_if_recur_tt< tuple< TupleLast >, Index, Action >
: conditional<
Action< TupleLast >::value
, integral_constant< size_t, Index >
, integral_constant< size_t, -1 > >::type
{};
// recursion
template<
typename TupleHead, typename... TupleRest
, size_t Index
, template< typename > class Action >
struct tuple_find_if_recur_tt<
tuple< TupleHead, TupleRest... >, Index, Action >
: conditional<
Action< TupleHead >::value
, integral_constant< size_t, Index >
, tuple_find_if_recur_tt<
tuple< TupleRest... >
, Index + 1u
, Action > >::type
{};
// wrap the recursion
template<
typename TupleType
, template< typename > class Action >
struct tuple_find_if_tt
: tuple_find_if_recur_tt< TupleType, 0u, Action >
{};
В качестве теста приведенный ниже код компилируется нормально:
// this works fine.
static_assert(
tuple_find_if_tt< tuple< int, float, double >
, is_same_type_tt< float >::type_tt >::value == 1, "" );
Но когда я пытаюсь использовать его с еще одним параметром шаблона, он не работает:
// problem starts from here...
template< typename... Types >
struct tuple_indirect_find_tt
{
typedef tuple< Types... > tuple_type;
// tuple_type obj_;
template< typename TypeLookingFor >
static constexpr size_t find()
{
return tuple_find_if_tt<
tuple_type
// something is not right below...
, typename is_same_type_tt< TypeLookingFor >::type_tt
>::value;
}
};
// this doesn't work.
static_assert(
tuple_indirect_find_tt< int, float, double >::find< float >()
== 1, "" );
Чтобы заставить его работать, мне пришлось реорганизовать классы шаблонов, чтобы я мог сделать следующее:
return tuple_find_if_tt<
tuple_type
, is_same_type_tt
, typename TypeLookingFor // this is separated from is_same_type_tt
>::value;
Обходной путь не кажется таким уж плохим, но мне все же хотелось бы знать, что я сделал не так. Если это не возможный подход, я хотел бы знать, какой стандарт С++ предотвращает это.
Спасибо за чтение.